Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 27.1Mb
PDF (A4) - 27.2Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


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

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

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

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

InnoDB バッファープールの内部動作や、その LRU の置き換えアルゴリズムの詳細については、セクション8.9.1「InnoDB バッファープール」を参照してください。

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

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

innodb_old_blocks_pctinnodb_old_blocks_time はどちらも動的かつグローバルであり、MySQL オプションファイル (my.cnf または my.ini) で指定するか、あるいは SET GLOBAL コマンドで実行時に変更できます。この設定を変更するには、SUPER 権限が必要です。

これらのパラメータを設定した場合の効果の測定に役立つように、SHOW ENGINE INNODB STATUS コマンドは追加の統計をレポートします。BUFFER POOL AND MEMORY セクションは次のようになります。

Total memory allocated 1107296256; in additional pool allocated 0
Dictionary memory allocated 80360
Buffer pool size   65535
Free buffers       0
Database pages     63920
Old database pages 23600
Modified db pages  34969
Pending reads 32
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 414946, not young 2930673
1274.75 youngs/s, 16521.90 non-youngs/s
Pages read 486005, created 3178, written 160585
2132.37 reads/s, 3.40 creates/s, 323.74 writes/s
Buffer pool hit rate 950 / 1000, young-making rate 30 / 1000 not 392 / 1000
Pages read ahead 1510.10/s, evicted without access 0.00/s
LRU len: 63920, unzip_LRU len: 0
I/O sum[43690]:cur[221], unzip sum[0]:cur[0]
  • Old database pages は、LRU リストの古いセグメント内のページの数です。

  • Pages made youngnot young はそれぞれ、新しくなった古いページの総数となっていないページの総数です。

  • youngs/snon-young/s はそれぞれ、このコマンドの最後の呼び出しのあと、古いページへのページアクセスによってこのようなページが新しくなった割合となっていない割合です。

  • young-making ratenot は、古いページへのアクセスだけでなく、全体的なバッファープールアクセスの点から見た場合、同じ割合を示しています。

注記

InnoDB モニターの出力で示される 1 秒あたりの平均は、現在の時間と 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 バッファープールの詳細は、セクション8.9.1「InnoDB バッファープール」を参照してください。


User Comments
Sign Up Login You must be logged in to post a comment.