雑多なインフラエンジニア日記

技術ブログでっす~

RDSの general_log を truncateする方法

general_log を truncate (正確にはrename&drop)するのに困ったのでメモ。

slow_log、general_log をAPIから参照でき、自動ローテートまでされる(ただし24h
分しか保持されない)ようになりましたが、途中でこれらのログ出力を無効にすると、
ローテートも止まるようです。

APIからのRDSログ監視について
http://xoxo-infra.hatenablog.com/entry/2013/03/12/205032


ローテートが止まる = ログテーブルは肥大したまま となってしまいます。

RDSで使用出来るユーザの権限の問題で、general_logに対して、truncateもdelete
も実行できないのですが、これを解消する為にRDSには、いくつかのストアドプロシ
ージャが用意されています。


・ストアドプロシージャ一覧は以下で確認できます。

mysql> SHOW PROCEDURE STATUS;



・今回実行するストアドプロシージャ

mysql> show create PROCEDURE rds_rotate_general_log\G
*************************** 1. row ***************************
Procedure: rds_rotate_general_log
sql_mode:
Create Procedure: CREATE DEFINER=`rdsadmin`@`localhost` PROCEDURE `rds_rotate_general_log`()
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE sql_logging BOOLEAN;
select @@sql_log_bin into sql_logging;
set @@sql_log_bin=off;
CREATE TABLE IF NOT EXISTS mysql.general_log2 LIKE mysql.general_log;
DROP TABLE IF EXISTS mysql.general_log_backup;
RENAME TABLE mysql.general_log TO mysql.general_log_backup, mysql.general_log2 TO mysql.general_log;
set @@sql_log_bin=sql_logging;
END
character_set_client: latin1
collation_connection: latin1_swedish_ci
Database Collation: latin1_swedish_ci
1 row in set (0.00 sec)

mysql> show tables;



中身を見ると解るのですが、general_logをgeneral_log_backupに退避していますので、
完全に削除するためには、2回ストアドプロシージャを実行する必要があります。


・general_log のデータを削除する。

mysql> select count(*) from general_log;
+----------+
| count(*) |
+----------+
| 660135 |
+----------+
1 row in set (11.69 sec)

mysql> call rds_rotate_general_log ;
Query OK, 0 rows affected, 1 warning (0.16 sec)

mysql> select count(*) from general_log;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)

mysql> SHOW PROCEDURE STATUS\G



・general_log_backup のデータも削除する。
(初回のストアド実行時に作成されている)

mysql> show tables;
+-------------------------------+
| Tables_in_mysql |
+-------------------------------+
| columns_priv |
| db |
| event |
| func |
| general_log |
| general_log_backup |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| host |
| ndb_binlog_index |
| plugin |
| proc |
| procs_priv |
| rds_global_status_history |
| rds_global_status_history_old |
| rds_heartbeat2 |
| rds_sysinfo |
| servers |
| slow_log |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+-------------------------------+
28 rows in set (0.01 sec)

mysql> select count(*) from general_log_backup;
+----------+
| count(*) |
+----------+
| 660135 |
+----------+
1 row in set (11.19 sec)

mysql> call rds_rotate_general_log;
Query OK, 0 rows affected (0.19 sec)

mysql> select count(*) from general_log_backup;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)

mysql>



これで無駄な領域が削除できました。
ログ有効→無効にしない限り、使うことは無さそうですね。

RDSに対して、SNSを使用しており、アラートメールが何回か飛んできたことを
きっかけに気づきました。

Message : The MySQL general and/or slow logs of the DB Instance: XXXX are consuming a large amount of provisioned storage.
Please refer to http://docs.amazonwebservices.com/AmazonRDS/latest/UserGuide/Appendix.MySQL.CommonDBATasks.html for more details.
The storage consumed by general and/or slow logs is at 10% of the provisioned storage
[Total: 489.99 MB] [Components: generalLogSize:233.07 MB,slowLogSize:20.61 KB,binlogSize:915.54 KB,innoDbLogSize:256.00 MB]



以上です。