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


15.8.3.5 バッファープールのフラッシュの構成

InnoDB は、バッファプールからのダーティページのフラッシュなど、特定のタスクをバックグラウンドで実行します。 ダーティページは、変更されたが、まだディスク上のデータファイルに書き込まれていないページです。

MySQL 8.0 では、バッファプールのフラッシュはページクリーナスレッドによって実行されます。 ページクリーナスレッドの数は、innodb_page_cleaners 変数 (デフォルト値は 4) によって制御されます。 ただし、ページクリーナスレッドの数がバッファプールインスタンスの数を超えると、innodb_page_cleaners は自動的に innodb_buffer_pool_instances と同じ値に設定されます。

ダーティページの割合が innodb_max_dirty_pages_pct_lwm 変数で定義された最低水位標値に達すると、バッファプールのフラッシュが開始されます。 デフォルトの最低水位標はバッファープールページの 10% です。 innodb_max_dirty_pages_pct_lwm 値が 0 の場合、この早期フラッシュ動作は無効になります。

innodb_max_dirty_pages_pct_lwm のしきい値の目的は、バッファプール内のダーティページの割合を制御し、ダーティページの量が innodb_max_dirty_pages_pct 変数で定義されたしきい値 (デフォルト値 90) に到達しないようにすることです。 バッファプール内のダーティページの割合が innodb_max_dirty_pages_pct しきい値に達した場合、InnoDB はバッファプールページを積極的にフラッシュします。

追加の変数により、バッファープールのフラッシュ動作を微調整できます:

  • innodb_flush_neighbors 変数は、バッファープールからページをフラッシュすると、同じエクステント内のほかのダーティーページもフラッシュするかどうかを定義します。

    • デフォルト設定の 0 は、innodb_flush_neighbors を無効にします。 同じエクステント内のダーティページはフラッシュされません。 シーク時間が重要な要因ではない非定期ストレージ (SSD) デバイスには、この設定をお勧めします。

    • 1 に設定すると、連続したダーティページが同じエクステントにフラッシュされます。

    • 2 に設定すると、ダーティページが同じエクステントでフラッシュされます。

    テーブルデータが従来の HDD ストレージデバイスに格納されている場合、隣接するページをある操作でフラッシュすると、個々のページを異なるタイミングでフラッシュする場合と比較して、I/O のオーバーヘッド (主にディスクシーク操作用) が削減されます。 SSD に格納されているテーブルデータの場合、シーク時間は重要な要因ではなく、この設定を無効にして書込み操作を分散できます。

  • innodb_lru_scan_depth 変数は、バッファプールインスタンスごとに、フラッシュするダーティページを検索するページクリーナスレッドスキャンをバッファプール LRU リストのどれだけ下に表示するかを指定します。 これは、ページクリーナスレッドによって毎秒 1 回実行されるバックグラウンド操作です。

    デフォルトより小さい設定は、通常、ほとんどのワークロードに適しています。 必要以上の値を指定すると、パフォーマンスに影響する可能性があります。 通常のワークロードでスペア I/O 容量がある場合のみ、値を増やすことを検討してください。 逆に、書込み集中型のワークロードが I/O の容量を満たしている場合は、特に大きなバッファプールの場合に値を減らします。

    innodb_lru_scan_depth をチューニングする場合は、小さい値から始めて、ゼロの空きページが表示されることがほとんどないという目標で設定を上方に構成します。 また、innodb_lru_scan_depth * innodb_buffer_pool_instances は毎秒ページクリーナスレッドによって実行される作業量を定義するため、バッファプールインスタンスの数を変更するときに innodb_lru_scan_depth を調整することを検討してください。

innodb_flush_neighbors および innodb_lru_scan_depth 変数は、主に書込み集中型のワークロードを対象としています。 DML アクティビティが重い場合、フラッシュが十分に積極的でないとフラッシュが遅れる可能性があります。または、フラッシュが過度に積極的であると、ディスク書込みが I/O の容量を満たす可能性があります。 理想的な設定は、ワークロード、データのアクセスパターン、およびストレージ構成 (たとえば、データが HDD または SSD デバイスのどちらに格納されているか) によって異なります。

適応型フラッシュ

InnoDB では、適応型フラッシュアルゴリズムを使用して、redo ログ生成の速度および現在のフラッシュ率に基づいてフラッシュ率を動的に調整します。 この目的は、フラッシュアクティビティが現在のワークロードに対応できるようにすることで、全体的なパフォーマンスをスムーズ化することです。 フラッシュレートを自動的に調整すると、バッファープールのフラッシュによる I/O アクティビティーのバーストが通常の読み取りおよび書き込みアクティビティーで使用可能な I/O 容量に影響する場合に発生する可能性があるスループットの急激なディップを回避するのに役立ちます。

多くの redo エントリを生成する書込み集中型のワークロードに通常関連付けられているシャープなチェックポイントは、スループットの急激な変更を引き起こす可能性があります。 シャープなチェックポイントは、InnoDB がログファイルの一部を再利用する場合に発生します。 これを行う前に、ログファイルのその部分に redo エントリがあるすべてのダーティページをフラッシュする必要があります。 ログファイルがいっぱいになると、シャープなチェックポイントが発生し、スループットが一時的に低下します。 このシナリオは、innodb_max_dirty_pages_pct のしきい値に達していない場合でも発生する可能性があります。

適応型フラッシュアルゴリズムは、バッファプール内のダーティページの数と redo ログレコードが生成される割合を追跡することで、このようなシナリオを回避するのに役立ちます。 この情報に基づいて、バッファプールから毎秒フラッシュするダーティページの数が決定され、ワークロードの突然の変更を管理できます。

innodb_adaptive_flushing_lwm 変数は、redo ログ容量の最低水位標を定義します。 このしきい値を超えると、innodb_adaptive_flushing 変数が無効になっていても適応型フラッシュが有効になります。

内部ベンチマークは、アルゴリズムが一定期間スループットを維持するだけでなく、全体的なスループットを大幅に向上させることもできることを示しています。 ただし、適応型フラッシュはワークロードの I/O パターンに大きく影響を与える可能性があり、すべての場合に適切であるとはかぎりません。 これがもっとも大きな利点をもたらすのは、Redo ログがいっぱいになるおそれがある場合です。 適応型フラッシュがワークロードの特性に適していない場合は、無効にできます。 適応型フラッシュは、デフォルトで有効になっている innodb_adaptive_flushing 変数によって制御されます。

innodb_flushing_avg_loops は、InnoDB が以前に計算したフラッシュ状態のスナップショットを保持する反復回数を定義し、適応型フラッシュがフォアグラウンドのワークロード変更にどの程度迅速に応答するかを制御します。 innodb_flushing_avg_loops 値が高いほど、InnoDB は以前に計算されたスナップショットを長く保持するため、適応型フラッシュの応答が遅くなります。 高い値を設定する場合は、redo ログ使用率が 75% (非同期フラッシュが開始されるハードコードされた制限) に達しないようにし、innodb_max_dirty_pages_pct のしきい値によってダーティページの数がワークロードに適したレベルに維持されるようにすることが重要です。

一貫性のあるワークロードを持つシステム、大きなログファイルサイズ (innodb_log_file_size) および 75% のログ領域使用率に達しない小さなスパイクでは、フラッシュをできるだけスムーズに保つために高い innodb_flushing_avg_loops 値を使用する必要があります。 負荷が非常に高いスパイクまたはログファイルが領域を多く提供しないシステムでは、フラッシュを小さくするとワークロードの変更を密接に追跡でき、75% のログ領域使用率への到達を回避できます。

フラッシュが遅れた場合、バッファープールのフラッシュ率は、innodb_io_capacity 設定で定義されているように、InnoDB で使用可能な I/O 容量を超えることがあります。 このような状況では、I/O アクティビティのスパイクがサーバーの I/O 容量全体を消費しないように、innodb_io_capacity_max 値によって I/O 容量の上限が定義されます。

innodb_io_capacity 設定は、すべてのバッファープールインスタンスに適用できます。 ダーティーページがフラッシュされると、I/O 容量はバッファープールインスタンス間で均等に分割されます。

アイドル期間中のバッファフラッシュの制限

MySQL 8.0.18 の時点では、innodb_idle_flush_pct 変数を使用して、アイドル期間 (データベースページが変更されない期間) 中のバッファプールのフラッシュ率を制限できます。 innodb_idle_flush_pct 値は、InnoDB で使用可能な I/O 操作数/秒を定義する innodb_io_capacity 設定の割合です。 デフォルトの innodb_idle_flush_pct 値は 100 で、これは innodb_io_capacity 設定の 100% です。 アイドル期間中のフラッシュを制限するには、100 未満の innodb_idle_flush_pct 値を定義します。

アイドル期間中のページフラッシュの制限は、ソリッドステートストレージデバイスの寿命を延長するのに役立ちます。 アイドル期間中のページフラッシュの制限の副作用には、長時間のアイドル期間後の停止時間が長くなり、サーバー障害が発生した場合のリカバリ期間が長くなることがあります。


関連キーワード:  InnoDB, フラッシュ, テーブル, 構成, プール, 設定, バッファ, ページ, ダーティページ, 適応