MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  ...  /  バッファープールをスキャンに耐えられるようにする

15.8.3.3 バッファープールをスキャンに耐えられるようにする

厳密な LRU アルゴリズムを使用するかわりに、InnoDB では、buffer pool に取り込まれ、再度アクセスされないデータ量を最小限に抑える手法を使用します。 目標は、先読みフルテーブルスキャンによって、その後アクセスされるかどうかわからない新しいブロックが読み取られた場合でも、頻繁にアクセスされるページ (ホットページ) が確実にバッファープール内に残るようにすることです。

新しく読み取られたブロックは、LRU リストの途中に挿入されます。 新しく読み取られたページはすべて、デフォルトでは LRU リストの末尾から 3/8 にあたる場所に挿入されます。 これらのページは、はじめてバッファープール内でアクセスされたときに、リストの前面 (直近で使用された端) に移動されます。 したがって、アクセスされないページでは LRU リストの先頭部分にアクセスされず、「エージアウト」は厳密な LRU アプローチより早くアクセスされます。 この配置では、LRU リストが 2 つのセグメントに分割されます。つまり、挿入ポイントの下流にあるページは古いとみなされ、LRU のエビクションの望ましい対象になります。

InnoDB バッファプールの内部動作および LRU アルゴリズムの詳細は、セクション15.5.1「バッファプール」 を参照してください。

LRU リストの挿入ポイントを制御し、テーブルスキャンまたはインデックススキャンによってバッファプールに入れられたブロックに InnoDB が同じ最適化を適用するかどうかを選択できます。 構成パラメータ innodb_old_blocks_pct は、LRU リスト内の古いブロックの割合 (%) を制御します。 innodb_old_blocks_pct のデフォルト値は 37 であり、元の固定された 3/8 の比率に対応します。 この値の範囲は、5 (バッファープール内の新しいページが非常に早く古くなります) から 95 (バッファープールの 5% しかホットページとして予約されないため、アルゴリズムがなじみのある LRU の方法に近くなります) までです。

バッファープールを先読みによって混乱した状態にならないように維持する最適化は、テーブルまたはインデックススキャンによる同様の問題も回避できます。 これらのスキャンでは通常、データページはすばやく連続して数回アクセスされ、それ以降は二度とアクセスされません。 構成パラメータ innodb_old_blocks_time は、あるページにはじめてアクセスしたあと、そのページが LRU リストの前面 (直近で使用された端) に移動されることなくアクセス可能になっている時間ウィンドウ (ミリ秒単位) を指定します。 innodb_old_blocks_time のデフォルト値は 1000 です。 この値を大きくすると、より多くのブロックがバッファープールから早く古くなる可能性があります。

innodb_old_blocks_pctinnodb_old_blocks_time の両方を MySQL オプションファイル (my.cnf または my.ini) で指定するか、SET GLOBAL ステートメントを使用して実行時に変更できます。 実行時に値を変更するには、グローバルシステム変数を設定するのに十分な権限が必要です。 セクション5.1.9.1「システム変数権限」を参照してください。

これらのパラメータの設定の影響を測定するために、SHOW ENGINE INNODB STATUS コマンドはバッファプール統計をレポートします。 詳細は、InnoDB 標準モニターを使用したバッファープールのモニタリングを参照してください。

これらのパラメータの効果はハードウェア構成、使用しているデータ、およびワークロードの詳細によって大幅に異なる場合があるため、パフォーマンスが重要な環境や本番環境でこれらの設定を変更する前には、常にベンチマークによってその有効性を確認してください。

ほとんどのアクティビティーが、大規模なスキャンにつながる定期的なバッチレポートクエリーを含む OLTP タイプである混在ワークロード環境では、バッチの実行中に innodb_old_blocks_time の値を設定すると、通常のワークロードのワーキングセットをバッファープール内に維持するのに役立つ場合があります。

バッファープール内に完全には収まらない大きなテーブルをスキャンする場合は、innodb_old_blocks_pct を小さな値に設定すると、1 回しか読み取られないデータがバッファープールの大きな部分を消費することはなくなります。 たとえば、innodb_old_blocks_pct=5 を設定すると、1 回しか読み取られないこのデータがバッファープールの 5% に制限されます。

メモリーに収まる小さなテーブルをスキャンする場合は、バッファープール内でページを移動するためのオーバーヘッドが低いため、innodb_old_blocks_pct をデフォルト値のままにするか、あるいは場合によっては (innodb_old_blocks_pct=50 などと) 増やすこともできます。

innodb_old_blocks_time パラメータの効果は、比較的効果の小さい innodb_old_blocks_pct パラメータに比べて予測が困難であり、ワークロードによる変動も大きくなります。 最適な値に到達するには、innodb_old_blocks_pct の調整によるパフォーマンス向上が不十分な場合は独自のベンチマークを実施してください。


関連キーワード:  InnoDB, テーブル, プール, 構成, ページ, old, blocks, インデックス, 圧縮, LRU