AmazonRDSは、デフォルトの設定ではslow queryを出力するようになっていない。
また、MySQLが動いているサーバにアクセスすることができないので、slow queryをログファイルに出力したとしてもそれを閲覧する術がない。
RDSでも採用されているMySQL 5.1からは、slow queryをテーブルに保存できるようになったので、それを使う。
方針
- ログはテーブル(mysql.slow_log)に出力する。
- 実行に1秒以上かかったクエリを記録する
- 100行以上を読み込んだクエリを記録する
普通なら以下のオプションをmy.cnfに設定すればOK。
[mysqld]
slow_query_log = ON
long_query_time = 1.000
log_output = TABLE
min_examined_row_limit=100
RDSの場合は、db-parameter-groupを作成し、パラメータを編集し、db-instanceに適用する。
今回はacme-param-grpというdb-parameter-groupを作成し、acmeというdb-instanceに適用する。
db-parameter-groupを作成
$ rds-create-db-parameter-group acme-param-grp -e MySQL5.1 -d "parameter group for acme"
db-parameter-groupのパラメータを編集
(log_outputはデフォルトでTABLEになっているので設定しない。設定しようとしてもできない)
$ rds-modify-db-parameter-group acme-param-grp \
--parameters="name=slow_query_log, value=ON, method=immediate" \
--parameters="name=long_query_time, value=1, method=immediate" \
--parameters="name=min_examined_row_limit, value=100, method=immediate"
methodに指定できる値はimmediate もしくは pending-reboot
編集したパラメータの確認
$ rds-describe-db-parameters acme-param-grp --source user
DBPARAMETER long_query_time 1 user integer dynamic true
DBPARAMETER min_examined_row_limit 100 user integer dynamic true
DBPARAMETER slow_query_log 1 user boolean dynamic true
sourceに指定できる値はuser 、system、 engine-default
db-parameter-groupをdb-instanceに適用
$ rds-modify-db-instance acme --db-parameter-group-name=acme-param-grp
db-instanceを再起動
$ rds-reboot-db-instance acme
db-instanceにdb-parameter-groupが適用されているか確認
$ rds-describe-db-instances
DBINSTANCE acme 2009-11-04T10:59:28.860Z db.m1.large mysql5.1 100 xxxx available acme.xxxxxxx.us-east-1.rds.amazonaws.com 3306 us-east-1d 1
SECGROUP xxxx active
PARAMGRP acme-param-grp in-sync
PARAMGRPがacme-param-grpになっていて、ステータスがin-syncになっていればOK。
さらにmysqlにアクセスしパラメータが有効になっているか確認する。
mysql > show global variables like 'slow_query_log';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| slow_query_log | ON |
+----------------+-------+
1 row in set (0.00 sec)
mysql> show global variables like 'long_query_time';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 1.000000 |
+-----------------+----------+
1 row in set (0.00 sec)
mysql> show global variables like 'min_examined_row_limit';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| min_examined_row_limit | 100 |
+------------------------+-------+
1 row in set (0.00 sec)