RDS for MySQL の general_log テーブル が破損する背景と対応

記事タイトルとURLをコピーする

CI部 佐竹です。
本日は、運用時のトラブル対応履歴より MySQL の general_log について記載します。

はじめに

RDS for MySQL の general_log (一般ログ) を作成し、データベーステーブルに書き込むには、DB パラメータグループのパラメータを設定する必要があります。

f:id:swx-satake:20210531164519p:plain

本キャプチャは、マネジメントコンソールにおける general_log に関するパラメータグループを表しています。本設定内容の詳細は以下に記載があります。

docs.aws.amazon.com

本設定を有効化 1 に設定している状態で RDS for MySQL を運用していると、稀に general_log が破損することがあります。本ブログでは、どのような状況で破損が起きるのかも記載します。

RDS for MySQL の general_log テーブル が破損したことを確認する

general_log テーブル が破損すると、以下の状況に陥ります。

  • ログに対する Select 文の結果が返らない
  • RDS DB Instance を再起動しても復旧しない
  • パラメータグループの設定を一度 0 に戻してから 1 に変更しても復旧しない

この状況に陥った場合、以下のクエリを実行してみてください。

select * from mysql.general_log;

以下の結果が返却された場合、 general_log は破損しています。

MySQL [mysql]> select * from mysql.general_log;
ERROR 1194 (HY000): Table 'general_log' is marked as crashed and should be repaired

参考:他の調査用SQL

参考まで、合わせて調査時に利用したクエリを記載します。

MySQL [mysql]> SHOW VARIABLES like 'general_log%';
+------------------+------------------------------------------+
| Variable_name    | Value                                    |
+------------------+------------------------------------------+
| general_log      | ON                                       |
| general_log_file | /rdsdbdata/log/general/mysql-general.log |
+------------------+------------------------------------------+

補足: general_log が有効になっているのか確認

MySQL [mysql]> SHOW VARIABLES like 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output    | TABLE |
+---------------+-------+

補足: general_log のアウトプットがどの形式なのか確認(今回は TABLE)

対応方法: repair の実行

以下は MySQL の公式ドキュメントとなりますが、この内容に従い repair table を実行し修復が可能です。

dev.mysql.com

repair table mysql.general_log;

Repair コマンド実行の際は、破損した行以降のデータは有効な行であっても失われる動作となることについてご留意ください。

クラッシュが発生する理由

1. テーブルの破損

CSV ストレージエンジンは MySQL の仕様として運用中にクラッシュする可能性があります。そして、ログテーブルは CSV ストレージエンジンです。

デフォルトでは、ログテーブルは、カンマ区切り値形式でデータを書き込む CSV ストレージエンジンを使用します。

MySQL :: MySQL 5.6 リファレンスマニュアル :: 5.2.1 一般クエリーログおよびスロークエリーログの出力先の選択

2. Snapshot から DB Instance 復元時に破損

RDS for MySQL において CSV ストレージエンジン等 InnoDB ストレージエンジン以外の MySQL ストレージエンジンを使用している場合、バックアップ(Snapshot)からの復元の際に、動作の信頼性が失われる場合があります。詳しくは以下に記載があります。

MySQL DB エンジン、自動バックアップは InnoDB ストレージエンジンでのみサポートされています。これらの機能を他の MySQL ストレージエンジン (MyISAM など) で使用すると、バックアップからの復元中に動作の信頼性が失われる場合があります。具体的には、MyISAM などのストレージエンジンは信頼性の高いクラッシュリカバリをサポートしていないため、クラッシュ時にテーブルが破損する可能性があります。このため、InnoDB ストレージエンジンを使用することをお勧めします。

バックアップの使用 - Amazon Relational Database Service

このため、general_log を TABLE で利用されている RDS を復元した場合は、本ログの Repair の必要があるかないか念のため確認する必要があるでしょう。

テーブルクラッシュへの恒久的な対応

クラッシュへの対応策として「破損を回避」しつつ、かつ CloudWatch から確認する方法は以下に記載されています。

aws.amazon.com

ログエクスポートの設定

f:id:swx-satake:20210531173826p:plain

RDS の設定を変更(Modify)し、必要なログの種類をチェックし保存します。

log_output パラメータの値を変更する

f:id:swx-satake:20210531173957p:plain

パラメータグループにおいて log_output パラメータの値を変更し FILE に設定します。

これらの設定を施すことで、CloudWatch Logs にログが転送されるようになります。

まとめ

f:id:swx-satake:20210531191955p:plain:w150

本ブログでは、RDS for MySQL で general_log テーブルがクラッシュした場合の対処方法と、その理由について記載しました。恒久対応として general_log テーブルのクラッシュを回避されたい場合は、CloudWatch Logs に転送すると良いでしょう。ただし CloudWatch Logs の利用料が発生する点はご留意ください。

最後に整理として、CloudWatch Logs へのログ転送設定は以下が完了している必要があるというまとめを記載します。

  1. パラメータグループにおいて general_log パラメータが有効 1 となっている
  2. パラメータグループにおいて log_output パラメータ値を FILE に設定
  3. RDS におけるログエクスポートの設定で General Log にチェックを行う

ではまたお会いしましょう。

佐竹 陽一 (Yoichi Satake) エンジニアブログの記事一覧はコチラ

マネージドサービス部所属。AWS資格全冠。2010年1月からAWSを利用してきています。2021-2022 AWS Ambassadors/2023-2024 Japan AWS Top Engineers/2020-2024 All Certifications Engineers。AWSのコスト削減、最適化を得意としています。