文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

AmazonRDS:ログ関連とログローテート

クラウドDBとして有名なAmazonRDSのログについてのお話です〜


f:id:treeapps:20180418131549p:plain

RDSはサーバのファイルシステムに直接アクセスする事ができません。

つまり、通常のクエリログ・slow-query-logをファイルとして出力できず、テーブル出力のみとなります。

ログテーブルは、mysqlスキーマにあり、対応は以下のようになっています。

クエリログ mysql.general_log engine = csv PK・KEYの設定無し。
slow-query-log mysql.slow_log engine = csv PK・KEYの設定無し。

まず、デフォルトでクエリログとslow-query-logは無効となっているので、

rds-modify-db-parameter-group パラメータグループ名 -p "name=general_log, value=1, method=immediate"

こんな感じで有効にする必要があります。

これらのテーブルで問題なのは、更新クエリの実行権限が無い、という点です。参照権限のみです。

つまり、ログをdelete・truncateする事はできません。ではどうやってログの世代管理をするか。なんと、世代管理用のストアドプロシージャが用意されています。

mysql> select name from mysql.proc where name like 'rds_%';
+------------------------+
| name                   |
+------------------------+
| rds_kill               |
| rds_kill_query         |
| rds_rotate_general_log | ← これがクエリログの世代管理
| rds_rotate_slow_log    | ← これがslow-query-logの世代管理
+------------------------+

ストアドが用意してあるのですが、ちょっと問題が・・それは、誤って2回連続ストアドを実行するとログが全削除されるという点です。これは怖い。ストアドの中身は以下のようになっています。

◆ ストアド実行前
general_log(ログが入っている)
◆ストアド実行1回目
general_log2をcreate。
general_log_backupをdrop。
general_log ーrename→ general_log_backup。(general_logがbackupになる)
general_log2 ーrename→ general_log。

こうなります。つまり、general_log のログは general_log_backup になります。
これをよく見ると解りますが、general_log_backupをdropするので、2回連続実行すると、綺麗さっぱりログが消えます・・

世代管理として使えるテーブルは、general_log と general_log_backup の2種類のみ。
そしてこれらのテーブルにはインデックスが設定されていない。
インデックスが無いということは、1000件前後しかデータを入れないだろう、という事なのでしょう。
ということは、1000件たまったらストアド実行で世代管理、みたいなスクリプトを書くのがいいと思われます。

まあこの辺が面倒なら、別のインスタンスに同構成のスキーマ用意して、そっちで管理する手もありますね。
↓こんなのを毎日cronで実行するとか。

create table if not exists hoge.general_log like mysql.general_log;
insert into hoge.general_log select * from mysql.general_log;
call rds_rotate_general_log();