mabots' blog

知のレバレッジを最大化せよ (旧はてなダイアリーから移転しました。)

MySQLサーバのLoad Averageが全体的に高いが、特定のクエリが遅いわけではない場合の対応

「ガツンと重いQueryが走っているわけでもないのになんとなくQueryがたまって結果的にMySQLサーバのLoad Averageが高い」というときに、統計的なアプローチが利用できます。

MySQL 5.1以前の場合

  • show full processlistを定期的に実効し、確率が高いクエリをあぶり出すアプローチ
  • これを自動化・カスタマイズを容易にするため、mprofileを利用することができる
  • http://developer.cybozu.co.jp/kazuho/2009/07/mysql-539d.html
  • サービスは無停止で出来る

MySQL 5.1以降の場合

  • 動的にslowqueryの閾値を極めて低くできる
  • 動的にログの吐き出し設定と吐き出し先がスイッチできる
  • この結果重たいときにリアルタイムにmysqldumpslowして集計できる
  • http://d.hatena.ne.jp/sh2/20090414
  • サービスは無停止で出来る (5.0等ではこの方法ではできない)

以下、mprofileを実際に利用してみます。

下準備。
$ yum install perl-CPAN
$ yum install perl-Jcode
$ yum install perl-JSON

チェックアウト
$ svn co http://svn.coderepos.org/share/platform/mysql/mprofile/trunk/
mprofile


Processlistの一定期間モニタリングとダンプ
$ time ./mpdump --samples=3000 --password="****" > mpdump.txt

3000件の場合は5min程度かかります。使い方は--helpを。

集計
$ ./mpfilter < mpdump.txt | ./mpreport | head -30 > result.txt


result.txtでは、
下記のような形で変数を省略しながらある程度マージしてくれます。
確率:Query Infoという書式です

0.200:SELECT *** FROM *** WHERE *** = ? LIMIT ?, ?
0.133:UPDATE ....

MySQL 5.1以降でも、slow query logのサイズなどを考えると、特定の時間帯に混み合っているような場合で、その時間帯に発行されるクエリを定常的にモニタリングしたい要な場合は、mprofileを利用すれば、かなり自動化出来ると思います。