MySQL 5.6と5.7のInnoDBバッファプールウォームアップのおはなし
mysql

MySQL 5.6と5.7のInnoDBバッファプールウォームアップのおはなし

このエントリーをはてなブックマークに追加

こんにちは、DBAです。

MySQL 5.6でInnoDBのバッファプールウォームアップが機能追加されました。みなさん使ってますか?

MySQL 5.6では正常終了時のダンプも起動時のロードもオフ、対してMySQL 5.7では両方ともオンです。また、MySQL 5.7ではダンプするバッファプールのページ数は(デフォルトでバッファプール全体の25%だけ、となっています。

わたしのオススメ設定は↓です。MySQL 5.6, 5.7両方でも使えるように、loose-接頭辞付きでinnodb_buffer_pool_dump_pct(5.7にあって5.6にないパラメーター)を書いています。

[mysqld]
loose-innodb_buffer_pool_dump_pct  = 100
innodb_buffer_pool_dump_at_shutdown= 1
innodb_buffer_pool_load_at_startup = 0

innodb_buffer_pool_dump_at_shutdownがONなので、mysqldの正常停止時にはバッファプールの内容を全てib_buffer_pool(デフォルト。ファイル名変更可能)に吐き出します。ib_buffer_poolに記録されるのはテーブルスペースIDとページIDだけなので、これでシャットダウンが重くなったことはありません。

さてこっちがポイント、innodb_buffer_pool_load_at_startupはOFFです。よって、mysqldは起動時に自動ではib_buffer_poolを読みません。

前提として、InnoDBのバッファプールをウォームアップするのは重い処理です。

  • 100GBのバッファプールを温めるには100GBの読み取りが必要です。
  • なのでそれなりに時間がかかることがあります。
  • その間フォアグラウンドスレッドの動作を遅くすることがあります。

たとえばmysqldがクラッシュするケース。
起動時にib_buffer_poolの読み込み(↑間違っても本番トラフィックと一緒にやらない方がいいやつ)が勝手に走ります。綺麗にロードバランスから外れていてくれればいいんですが、切り離される前にmysqld_safeがmysqldを再起動しちゃってトラフィックが流れてくるままの状態になっちゃってただでさえバッファプールはあったまってないし いつのものだかわからない (そう、だってib_buffer_poolは 正常終了 時に作られるので、異常終了した時は作ってくれないのですよ) ib_buffer_poolの内容でバッファプールをあっためるためにI/O使いまくるしわーロードアベレージ500行ったよアッー!

(´・ω・`) SHOW PROCESSLISTが刺さった

なんてことが起こらないように、OFFにしています。たとえです。たとえ。

クラッシュの場合そもそもib_buffer_poolファイルの中身そのものがあてにならないので自動で読み込む必要はないし、正常終了させた(何らかの人の意図で停止させた)場合なら、手でSET GLOBAL innodb_buffer_pool_load_now= 1と叩いてバッファプールのウォームアップが終わるまでの間は切り離したままにすればいいだけなので、この設定の方が安全です。なお、SET GLOBAL innodb_buffer_pool_load_now= 1で走り始めたウォームアップ(バックグラウンドで走るので、戻り自体は一瞬です)を止めるには、SET GLOBAL innodb_buffer_pool_load_abort=ONを使います。マニュアルが軒並みSET innodb_buffer_pool_load_abortって書いてあるけどグローバル変数なのでSET GLOBALでないとダメだよ! ばぐれぽ

( ´-`).oO(MySQL 5.7のinnodb_buffer_pool_dump_pctが25なのはこんな悲しい事故を防ぐため…?

とかふと思ったり思わなかったり。


名無しのエンジニア
今年もGMOファミリースマイルデーがありました
Tableau Serverで簡単にMySQLテーブルの容量(概算値)を時系列でモニタリング