MySQLとRDS MySQLとRDS Auroraのキャッシュウォーミング機能を調べた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

データベースのキャッシュウォームアップについて

キャッシュを活用して高速にクエリーをさばいているDBシステムも、リスタートなどのタイミングでキャッシュが失われると、途端に処理性能が著しく低下します。 そのようなケースに備えて、有名なDBシステムではスタート時にダンプ済みキャッシュを読み込んでウォームアップする機能が提供されています。

今回は以下の MySQL 系データベースについてキャッシュウォーミング機能を確認しました。

  • MySQL 5.6
  • RDS MySQL 5.6
  • MySQL 5.7
  • RDS Aurora

それでは順に見ていきましょう。

MySQL 5.6

InnoDB で MySQL を使っている場合、クエリーキャッシュは buffer pool に保存されます。 buffer pool はメモリー上にあるため、MySQL を一旦停止すると失われてしまいます。

この問題を解決するために buffer pool をファイルシステムに入出力する機能が MySQL 5.6.3 から導入されました。

ファイルに出力する

即時出力するためには

mysql > SET GLOBAL innodb_buffer_pool_dump_now= ON;

正常終了時に出力するためには

mysql > SET GLOBAL innodb_buffer_pool_dump_at_shutdown=ON;

常にこの設定を有効にするのであれば my.cnf で

[mysqld]
  innodb_buffer_pool_dump_at_shutdown=ON

とします。

MySQL が異常終了し、buffer pool が書き出されないケースに備えて innodb_buffer_pool_dump_now を定期的に呼び出すとシステムはより堅牢になります。

ファイルから読み込む

即時に読み込むには

mysql > SET GLOBAL innodb_buffer_pool_load_now=ON;

即時読み込みをキャンセルするには

mysql > SET GLOBAL innodb_buffer_pool_load_abort=ON;

起動時に読み込むには my.cnf で

[mysqld]
  innodb_buffer_pool_load_at_startup=ON

とします。

RDS for MySQL 5.6

RDS for MySQL では 5.6.19 から Innodb の Cache Warming に対応しました。

機能発表時に弊社ブログでも解説しております。

https://dev.classmethod.jp/cloud/aws/rds-for-mysql-cache-warming/

以下では 5.6.19 以上のバージョンを前提とします。

RDS はファイルシステムの操作が制限されているため、通常の MySQL と同様の手順で実行しても、次のような権限周りのエラーが発生します。

mysql> SET GLOBAL innodb_buffer_pool_load_abort=ON;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation

そのため

  • パラメーターグループ
  • ストアドプロシージャ

で制御します。

パラメーターグループで制御するもの

  • innodb_buffer_pool_dump_at_shutdown
  • innodb_buffer_pool_load_at_startup

についてはパラメーターグループで制御します。 デフォルトではともに OFF(=0) となっています。

ストアドプロシージャで制御するもの

即時実行する

  • innodb_buffer_pool_dump_now
  • innodb_buffer_pool_load_now
  • innodb_buffer_pool_load_abort

は rds_ が接頭するストアドプロシージャ経由で実行します。 具体的には

mysql > CALL mysql.rds_innodb_buffer_pool_dump_now();
mysql > CALL mysql.rds_innodb_buffer_pool_load_now();
mysql > CALL mysql.rds_innodb_buffer_pool_load_abort();

というようになります。

MySQL 5.7

MySQL 5.7.2 と 5.7.7 で Cache Warming 周りの機能追加が行われました。 以下ではより新しい 5.7.7 以降を前提とします。

  • innodb_buffer_pool_dump_at_shutdown
  • innodb_buffer_pool_load_at_startup

はともにデフォルトで ON となり、buffer pool が MySQL の終了・停止で引き継がれるようになりました。

また、新規グローバル変数 innodb_buffer_pool_dump_pct が追加され、ダンプする buffer pool の割合を指定できるようになりました。 デフォルトは 25 となっており、キャッシュが乗っかっているページの新ものから 25% 分がダンプされます。

割合を変更するには

mysql > SET GLOBAL innodb_buffer_dump_pct=40;

常にこの設定にするのであれば my.cnf で

[mysqld]
  innodb_buffer_dump_pct=40

とします。

RDS Aurora

"Survivable" Cache Warming

Aurora ではキャッシュ管理は別プロセスになっており、独自のの機構でクエリーキャッシュやDBシステムリスタート時の Cache Warming を実現しているそうです。 (Aurora 系ドキュメントでは "Survivable" Cache Warming と形容されています)

この "Survivable" Cache Warming をコントロールするパラメーターグループを探したのですが、見つけられませんでした。 ご存じの方は教えて下さい。

キャッシュヒットに関する CloudWatch メトリクス

BufferCacheHitRatio : The percentage of requests that are served by the Buffer cache. ResultsetCacheHitRatio : The percentage of requests that are served by the Resultset cache.

という Aurora 固有のクエリーキャッシュ系メトリクスが追加されています。

innoDB のキャッシュ系パラメーターの扱い

パラメーターグループには InnoDB 向けの

  • innodb_buffer_pool_dump_at_shutdown
  • innodb_buffer_pool_load_at_startup

が残っていますが、これらが OFF(=0) のままDBをリスタートしても、SELECT でキャッシュヒットすることが確認できました。 (メトリクス BufferCacheHitRatio の値から類推)

その他

特定のデータベースに依存しないウォームアップとしては、起動直後に SQL を流すアプローチがよく知られています。

参考

MySQL 5.6

MySQL 5.6 RDS

MySQL 5.7

RDS Aurora