はじめに
MySQL には、redo ログと呼ばれるクラッシュリカバリ用のトランザクションデータを保存するファイルが存在しています。
これまで、この redo ログを変更するためには一度 mysqld プロセスを再起動する必要がありました。
MySQL 8.0.30 ではこの redo ログのサイズを動的に変更することが可能になっており、またそれに関連するいくつかのステータス変数が追加されています。
今回は、これまでの redo ログの機能と比較をおこないながら、この新機能について確認してみたいと思います。
MySQL 8.0.29 までの挙動
redo ログのサイズと概要について
これまで redo ログのサイズは、以下のシステム変数によって制御されていました。
システム変数名 | デフォルト値 | 説明 |
---|---|---|
innodb_log_file_size | 50331648(50MB) | 各 redo ログファイルのサイズを定義します。「innodb_log_file_size * innodb_log_files_in_group」の値が 512GB 以下になるように設定する必要があります。 |
innodb_log_files_in_group | 2 | ロググループ内のログファイルの数を定義します。 |
redo ログファイルは innodb_log_group_home_dir に出力され、値が指定されていない場合はデフォルトでデータディレクトリに出力されます。
また、ib_logfile0、ib_logfile1、と数に応じて ib_logfileN の形式で連番でファイルが作成され、これらのファイルが循環方式で利用されています。
1 2 3 |
# ls -l /var/lib/mysql/ib_logfile* -rw-r----- 1 mysql mysql 50331648 8月 9 00:06 /var/lib/mysql/ib_logfile0 -rw-r----- 1 mysql mysql 50331648 6月 15 12:43 /var/lib/mysql/ib_logfile1 |
redo ログのサイズの変更方法について
redo ログのサイズを変更する場合は、以下の手順で実施する必要があります。
-
MySQL サーバーをシャットダウンして、エラーが発生しないことを確認します
1# systemctl stop mysqld -
設定ファイル(my.cnf)を編集して、innodb_log_file_size や innodb_log_files_in_group を変更します。
1234# vi /etc/my.cnf(...)innodb_log_file_size = 500Minnodb_log_files_in_group = 2 -
MySQL サーバーを再起動します
1# systemctl start mysqld
再起動時に redo ログファイルのサイズが異なっていることが検知されると、InnoDB のチェックポイント処理が実行されます。その後、古いログファイルは閉じて削除されて、新しいサイズでログファイルが作成されて開かれます。
redo ログの見積もり方法について
redo ログファイルの使用状況については、InnoDB 標準モニター(SHOW ENGINE INNODB STATUS) の LOG セクションから確認することができます。
1 2 3 4 5 6 7 8 9 10 11 |
--- LOG --- Log sequence number 4099314226 Log buffer assigned up to 4099314226 Log buffer completed up to 4099314226 Log written up to 4099314226 Log flushed up to 4099054499 Added dirty pages up to 4099314226 Pages flushed up to 4013445677 Last checkpoint at 4013445677 |
このうち、Log sequence number(LSN) が redo ログに書き込まれた合計バイト数、Last checkpoint at が最後にチェックポイント処理が実行された LSN を示しています。
redo ログの使用量は全体の 75% 以下にすることが推奨されているため、ピーク時における「Log sequence number – Last checkpoint at」の値が、redo ログファイル全体の 75% を超えないように注意する必要があります。
たとえば、上記の例だと 85MB が使用されているため、redo ログの合計サイズは余裕をもって 150MB 程度にすると良いと判断することができます。
ただし、redo ログのサイズの見積もりは慎重におこなう必要がある上、チェックポイント処理やディスク I/O の設定によっても redo ログの使用量の目安は変化していきます。
そのため、たとえば更新量が多い時間帯における 1 時間の Log sequence number の増加分を確認して redo ログのサイズを見積もるなど、システムに応じて適切な値を設定するようにしてください。
MySQL 8.0.30 からの挙動
redo ログのサイズと概要について
MySQL 8.0.30 からは、シンプルに以下のシステム変数でサイズが制御されるようになりました。
システム変数名 | デフォルト値 | 説明 |
---|---|---|
innodb_redo_log_capacity | 104857600(100MB) | redo ログファイルとして利用する容量を定義します。この値が定義されていない場合、代わりに「innodb_log_file_size * innodb_log_files_in_group」がこの値として設定されます。 |
このシステム変数の追加にともない、これまでの innodb_log_file_size と innodb_log_files_in_group を指定することは非推奨となっているので注意してください。
また、出力先は innodb_log_group_home_dir から変化していませんが、新しく #innodb_redo ディレクトリが作成されるようになり、redo ログファイルはこのディレクトリ内で管理されるようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# ls -ld /var/lib/mysql/#innodb_redo drwxr-x--- 2 mysql mysql 4096 8月 16 11:32 /var/lib/mysql/#innodb_redo # ls -lh /var/lib/mysql/#innodb_redo 合計 100M -rw-r----- 1 mysql mysql 3.2M 8月 16 11:32 #ib_redo10_tmp -rw-r----- 1 mysql mysql 3.2M 8月 16 11:32 #ib_redo11_tmp -rw-r----- 1 mysql mysql 3.2M 8月 16 11:32 #ib_redo12_tmp (...省略...) -rw-r----- 1 mysql mysql 3.2M 8月 16 11:32 #ib_redo36_tmp -rw-r----- 1 mysql mysql 3.2M 8月 16 11:34 #ib_redo5 -rw-r----- 1 mysql mysql 3.2M 8月 16 11:32 #ib_redo6_tmp -rw-r----- 1 mysql mysql 3.2M 8月 16 11:32 #ib_redo7_tmp -rw-r----- 1 mysql mysql 3.2M 8月 16 11:32 #ib_redo8_tmp -rw-r----- 1 mysql mysql 3.2M 8月 16 11:32 #ib_redo9_tmp |
ファイル名は使用している #ib_redoN と予備用の #ib_redoN_tmp に分かれており、使い切ると新しい番号のファイルが生成されていきます。
また、ファイル数は 32 個で固定されており、各ファイルのサイズは「1/32 * innodb_redo_log_capacity」になります。
redo ログのサイズの変更方法について
redo ログのサイズを変更する場合は、MySQL 8.0.29 までのように設定ファイルを変更して再起動することもできますが、以下のように動的に変更することが可能になっています。
1 |
mysql> SET GLOBAL innodb_redo_log_capacity = 5*1024*1024*1024; |
また、redo ログのサイズの変更状況については、新しく追加された以下のステータス変数で確認することが可能です。
-
Innodb_redo_log_resize_status
redo ログのサイズの変更状況を示します。以下の値を取ることがあります。- OK : 問題はなく、保留中のサイズ変更作業もない
- Resizing down : サイズを縮小させる作業が進行中
なお、サイズを増やす作業については、瞬間的におこなわれるため保留中の表示は用意されていないようですが、実際にはトランザクションやチェックポイント処理の実行状況に応じて、徐々にファイルサイズが増加していく様子が確認できます。
12345678910# ls -lh /var/lib/mysql/#innodb_redo/合計 885M-rw-r----- 1 mysql mysql 3.2M 8月 16 12:58 #ib_redo565(...省略...)-rw-r----- 1 mysql mysql 3.2M 8月 16 12:58 #ib_redo591-rw-r----- 1 mysql mysql 160M 8月 16 12:58 #ib_redo592-rw-r----- 1 mysql mysql 160M 8月 16 12:58 #ib_redo593_tmp-rw-r----- 1 mysql mysql 160M 8月 16 12:58 #ib_redo594_tmp-rw-r----- 1 mysql mysql 160M 8月 16 12:58 #ib_redo595_tmp-rw-r----- 1 mysql mysql 160M 8月 16 12:58 #ib_redo596_tmp -
Innodb_redo_log_capacity_resized
現在の redo ログのサイズを確認できます。サイズを縮小している作業が進行中の場合、徐々に減っていく様子が確認できます。
redo ログの見積もり方法について
redo ログの使用量に関しても、以下のステータス変数が追加されています。
-
Innodb_redo_log_current_lsn
現在の LSN を表示します。SHOW ENGINE INNODB STATUS の LOG セクションにおける Log sequence number と一致しています。 -
Innodb_redo_log_checkpoint_lsn
最後にチェックポイント処理が実行された LSN を表示します。SHOW ENGINE INNODB STATUS の LOG セクションにおける Last checkpoint at と一致しています。
redo ログファイルのサイズを見積もる場合は、これまでと同様に見積もることが可能です。また、MySQL 8.0.30 からはステータス変数として表示できるようになっているため、定期的な値の確認や監視がしやすくなっています。
まとめ
ここまで、新しく実装された redo ログファイルサイズの動的変更について確認しました。
MySQL 5.7 ではバッファプールサイズの動的変更が可能になりましたが、MySQL 8.0.30 からは redo ログファイルサイズが動的に変更できるようになり、システムの負荷状況に応じて柔軟に対応できるようになってきました。
また、SHOW ENGINE INNODB STATUS の結果からしか確認できなかった内容の一部も SHOW STATUS で確認できるようになっており、redo ログの状況が管理しやすくなったのではないかと思います。
MySQL 8.0 のリリースからだいぶ経ちますが、新規機能はまだまだ追加されているので、今後も リリース情報からは目が離せなさそうです。