MySQL道普請便り

第184回MySQL innodb_buffer_poolのウォームアップ周りのオプション

InnoDBストレージエンジンを扱うときにMySQLを再起動したときや、通常とは違うクエリを大量に流し終えた直後でinnodb_buffer_poolが荒れている場合、普段ではinnodb_buffer_poolに載っていたであろうはずのデータやインデックスが載っておらず、最初のうちはパフォーマンスが安定しないときがあります。これは時間がたつことでinnodb_buffer_poolがあたたまり、解決することがありますが、MySQLではこの一連の流れをウォームアップと説明しています。

MySQLはバージョン5.6からinnodb_buffer_pool_dump_at_shutdown、innodb_buffer_pool_load_at_startupという2つのオプションがあり、ウォームアップを高速化してbuffer_poolの中身をメモリに戻すことができるようになっています。今回はこのウォームアップ処理周りのオプションについて紹介します。

innodb_buffer_poolのdump

メモリ上にあるinnodb_buffer_poolの内容のdumpは、下記を実行することですぐに取得することができます。

mysql> SET GLOBAL innodb_buffer_pool_dump_now=ON;

取得後はdatadirの中にib_buffer_poolというファイルができあがります。これがinnodb_buffer_poolをdumpしたファイルになります。dumpしたファイルはデータそのものが入っているわけではなく、テーブルスペースidとページidがカンマ区切りで入っているため、大きなファイルではありません。実際にlessコマンド等で確認すると、カンマ区切りの2つの数字が確認できるかと思います。

$ less ib_buffer_pool
4294967294,2402
4294967277,60
4294967277,53
〈省略〉

このib_buffer_poolの中身は、innodb_buffer_pool_dump_pct(1~100)の値を設定することで、何%をdumpするか指定することができます。デフォルトでは25となっており、全体の1/4がdumpされることになります。

mysql> show variables like '%innodb_buffer_pool_dump_pct%';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| innodb_buffer_pool_dump_pct | 25    |
+-----------------------------+-------+
1 row in set (0.01 sec)

また、innodb_buffer_pool_dump_at_shutdownというオプションがあり、これがONの状態であれば、シャットダウン時にdumpファイルを作成します。このオプションはバージョン5.7以降でデフォルトONになっています。

2022-01-25T01:25:10.468379+09:00 0 [Note] [MY-011944] [InnoDB] Dumping buffer pool(s) to /path/to/ib_buffer_pool

innodb_buffer_poolのload

dumpしたファイルはinnodb_buffer_pool_load_nowを実施することでloadすることが可能です。load自体はバックグラウンドで実行されるため、応答自体はすぐに返ってきます。

mysql> SET GLOBAL innodb_buffer_pool_load_now=ON;
Query OK, 0 rows affected (0.00 sec)

また、innodb_buffer_pool_load_at_startupをONにすることで、ib_buffer_poolファイルが存在すれば起動時に自動でloadを開始してくれます。こちらもバージョン5.7でデフォルトONになっています。

loadが完了すると完了したログが出力されます。

2022-11-08T01:09:00.724600+09:00 0 [Note] [MY-011946] [InnoDB] Buffer pool(s) load completed at 221108  1:09:00

dump / loadの状態の確認

innodb_buffer_pool_sizeが小さい場合はすぐに完了しますが、非常に大きい場合に進捗を確認することができます。dumpやloadの状態を確認するには2通りあります。

SHOW STATUSで確認

SHOW STATUSコマンドのInnodb_buffer_pool_dump_statusとInnodb_buffer_pool_load_statusで、dumpとloadそれぞれのステータスを確認することができます。

mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_%_status';
Query OK, 0 rows affected (0.00 sec)
+----------------------------------+------------------------------------+
| Variable_name                    | Value                              |
+----------------------------------+------------------------------------+
| Innodb_buffer_pool_dump_status   | Dumping of buffer pool not started |
| Innodb_buffer_pool_load_status   | Loaded 1/1582 pages                |
| Innodb_buffer_pool_resize_status |                                    |
+----------------------------------+------------------------------------+
3 rows in set (0.00 sec)

performance_schemaで確認

performance_schemaでloadの状態を確認するには、進捗中の場合はevents_stages_current、loadが完了した場合はevents_stages_historyで確認することができます。

ただし、performance_schemaで確認するにはstage/innodb/buffer pool loadのインストゥルメントを有効にする必要があります。詳細なやり方については公式ドキュメントのパフォーマンススキーマを使用したバッファプールのロード進行状況の監視をご確認ください。

mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_history;
+-------------------------------+----------------+----------------+
| EVENT_NAME                    | WORK_COMPLETED | WORK_ESTIMATED |
+-------------------------------+----------------+----------------+
| stage/innodb/buffer pool load |           1582 |           1582 |
| stage/innodb/buffer pool load |           1582 |           1582 |
| stage/innodb/buffer pool load |           1582 |           1582 |
| stage/innodb/buffer pool load |           1582 |           1582 |
| stage/innodb/buffer pool load |           1582 |           1582 |
+-------------------------------+----------------+----------------+

存在しないテーブルスペースidがdumpに書き込まれている場合

存在しないテーブルスペースidがdumpに書き込まれている場合は、エラーとなりloadに失敗します。実際に、ib_buffer_poolを文字列や存在しないテーブルスペースidに書き換えてloadを実行すると、エラーが返ってくることが確認できました。

〈table_space_idに文字列を埋め込んだ場合〉
2022-11-08T01:30:40.246671+09:00 0 [Note] [MY-011946] [InnoDB] Loading buffer pool(s) from /path/to/ib_buffer_pool
2022-11-08T01:30:40.246772+09:00 0 [ERROR] [MY-011947] [InnoDB] Error parsing '/path/to/ib_buffer_pool', unable to load buffer pool (stage 1)
〈存在しないtable_space_idがあった場合〉
2022-11-08T01:31:53.013564+09:00 0 [Note] [MY-011946] [InnoDB] Loading buffer pool(s) from /path/to/ib_buffer_pool
2022-11-08T01:31:53.014010+09:00 0 [ERROR] [MY-011947] [InnoDB] Error parsing '/path/to/ib_buffer_pool': bogus space,page 11114294967294,3530 at line 0, unable to load buffer pool

まとめ

今回は、innodb_buffer_poolのウォームアップ処理の高速化方法として、ウォームアップ処理関連のオプションを紹介しました。バージョン5.7以降デフォルトでONになっているので意識することは少ないかもれしませんが、停止時や起動時にこういった処理がバックグランドで実行されているということを認識しておくと良いかと思います。

より詳細な内容については、公式ドキュメントにも記載があるのでこちらもご参照ください。

おすすめ記事

記事・ニュース一覧