2016年1月15日金曜日

AnemometerというMySQLスローログ専用の可視化ツールの弱点と、その克服スクリプト

一部の人にしか知られていない Anemometer というMySQLのスローログ専用の可視化ツールがある。

box/Anemometer: Box SQL Slow Query Monitor


中身はpt-query-digestの テーブル出力機能 (サマライズした結果をMySQLのテーブルに保存する機能があるのだ)に依存していて、スローログの可視化というよりはpt-query-digestの可視化というのがたぶん正しい。

だけどこのやり方にはちょっと弱点があって、pt-query-digestはクエリーをサマライズする時に発生時間の情報を 「そのダイジェストが最初に現れた時間(ts_min)」と「そのダイジェストが最後に現れた時間(tx_max)」 という値にサマライズしてしまう。よく見る出力結果の中では"Time range"として表示されている。


# Query 14: 0.00 QPS, 0.00x concurrency, ID 0xAF17C328E1020443 at byte 10391443
# This item is included in the report because it matches --outliers.
# Scores: V/M = 13.70
# Time range: 2015-11-02 10:55:08 to 2015-12-18 15:20:14
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count          0      13
# Exec time      0    163s      2s     51s     13s     29s     13s      9s
# Lock time      0     5ms   271us   445us   354us   424us    65us   301us
# Rows sent      9 544.87k   3.91k 104.73k  41.91k  97.04k  33.62k  46.68k
# Rows examine   0  12.00M 238.87k   3.04M 945.00k   1.46M 808.81k 725.01k
# Query size     0  24.29k   1.87k   1.87k   1.87k   1.86k    0.00   1.86k

コマンドラインからの出力結果を眺める分には便利なんだけど、グラフ化しようという時にこれはつらい。Anemometerはts_min(最初にスローログに現れた時刻)をグラフにプロットするので、今既にあるスローログをpt-query-digestで食わせてAnemometerで表示させると、チェックサムごとにts_minの時刻に1回だけスパイクしたようなグラフになってしまう。

これは、上手くない(´・ω・`)






pt-query-digest側でこの集約を無効化できればいいんだけど、オプションとしては存在せず、中に手を入れるにしても結構奥まったところにあっていじくりたくない。

定期的にpt-query-digestに--since, --until オプションを使って食わせてもいいんだけど、秒単位とは言わずとも分単位くらいでは見たい…となると、1日ぶんのログファイルを食わせるのに見るかどうかもわからないのに1440回pt-query-digestを起動しなければならない。それも嫌だ。


という訳で乱雑に書いたPerlスクリプト。Anemometer用にスローログを食ってくれるのでanemoeater(どや
my_script/anemoeater.pl at master · yoku0825/my_script
yoku0825/anemoeater


$ ./anemoeater.pl --docker path_to_slowlog

シンプル。--dockerを使わなくとも、Anemometerが既に構成されている環境があれば、--hostとか--userで指定してやればいい。--dockerに任せると構成済みの yoku0825/anemometer を起動して、スクリプトで1分ごとに丸めて送る。

パイプでpt-query-digestを呼ぶので結構遅い(11Mのスローログを食わせるのに、pt-query-digestで直接食わせると10秒ちょい、anemoeaterだと24パラにしても1分ちょい)

これで無事、過去のスローログをまとめて食わせても




ちゃんとジグザグしてくれるようになった。

2015/12/01 00:00~2016/01/01 23:59のログを8並列でぶち込むのはこんな感じで書きます。

$ ./anemoeater.pl --since 201512010000 --until 201601012359 --parallel 8 --docker path_to_slowlog
real    0m17.471s
user    1m47.847s
sys     0m11.117s

これでDockerでAnemometerの起動まで終わってるんだから、都度都度パースして突っ込めそう。しめしめ。


【2016/02/03 17:43】
yoku0825/anemoeater として別リポジトリーにしました。

2016年1月14日木曜日

MySQL Bug #79977 "utf8mb4_unicode_520_ci don't make sense for Japanese FTS" で言いたいこと

英語で書いてたら自分でもよくわからなくなってきたので。

MySQL Bugs: #79977: utf8mb4_unicode_520_ci don't make sense for Japanese FTS


* 本質的には MySQL Bugs: #76553: Sushi-Beer issue of MySQL with utf8mb4 の関連。
  * Unicode実装が不完全だから起こっている問題。


* 丸め問題

  * motherを意味する書き方に、はは(ひらがな)とハハ(カタカナ)とハハ(半角カタカナ)があって、
  * これらは(文字の形は違うけど)同じ音で同じ意味だから、大概の場合同じ文字として扱ってくれると嬉しい。


* 病院美容院問題

  * hospitalを意味する"びょういん"とheir salonを意味する"びよういん"
  * "ょ"と"よ"は文字の形は似てるけど、ほとんどの場合これは違う意味を持つから区別しないといけない。


* ハハパパ問題

  * Bug #76553でも説明されてるけど、ハハ(濁音なし)はmother、ババ(濁点)は"grand mother"、パパ(半濁点)は"daddy"を意味する。
  * これらは区別されないと困る。超困る。


* 最後に半角全角問題

  * "MySQL"と"MySQL"は同じに扱いたいよね。

* Hiragana-Katakanaと半角全角を区別しちゃうのは、不便だけど我慢できる。
* でも拗音促音と濁点半濁点を区別 *されない* のは(特に全文検索の側面で)機能要件を満たせない。LIKE演算子でもそうだけど。
  * 「びょういん」って検索して美容院が結果に含まれたら変でしょ?
* あと、これ、UNIQUE制約をぶっ壊す可能性があるのよね。
  * UNIQUE KEY(家族関係)って制約があって、俺には母親がいるからハハって入れて、俺に父親がいるからパパって入れようとすると、エラるよね? (いわゆる kamipoさんのハハパパ問題


表にまとめるとこんな感じ。ホントはutf8mb4_japanese_ciが欲しいところだよねって。

|                    | utf8mb4_bin | utf8mb4_general_ci | utf8mb4_unicode_ci | utf8mb4_unicode_520_ci|
|--------------------|-------------|--------------------|--------------------|-----------------------|
| Hiragana-Katakana  | cs (unkind) | cs (unkind)        | ci (good)          | ci(good)              |
| Youon              | cs (good)   | cs (good)          | ci (critical)      | ci(critical)          |
| Dakuten-Handakuten | cs (good)   | cs (good)          | ci (critical)      | ci(critical)          |
| Wide-Narrow        | cs (unkind) | cs (unkind)        | ci (good)          | ci(good)              |
| Sushi-Beer         | cs          | ci                 | ci                 | cs                    |

2016年1月13日水曜日

MySQL 5.7.11でdefault_password_lifetimeのデフォルトが0になるらしい!

日々の覚書: MySQL 5.7.4で導入されたdefault_password_lifetimeがじわじわくる の公開以来大反響をいただいていた (ブクマ がすごいことになっていて、思わず ばぐれぽ にブクマのリンクを貼り付けたほど)default_password_lifetime が。

5.7.11でついにデフォルト0になる!!! やった!!! やったよ!!!

ドキュメントはもう"default: 0 (>= 5.7.11)"の記載になってる。


これで、

MySQL 5.7にアップデートしてから

360日後にやってくる

_人人人人人人_
> 突然の死 <
 ̄Y^Y^Y^Y^Y^Y^ ̄

はなくなりました! (∩´∀`)∩ワーイ


いいぞ○racle!
"Affects me"してくれたみなさんもありがとうございました。


( ´-`).oO(さて、また自分が罠にならないように、あちこちのもの直さないとなー


【2015/01/14 13:59】
MySQL Bugs: #77277: default_password_lifetime should be set 0 as implicit default value

の最後の方で、Morgan Tocker(Oracle MySQL Community Manager改めOracle MySQL Product Manager)が他にも色々(default_password_filetime > 0だったらワーニング出そうぜ とか SYSスキーマでいつexpireされるか見るビュー作ろうぜ とか)出してくれてる。



@morgo++