InnoDB
mutexes および rw-locks は通常、短い間隔で予約されています。 マルチコアシステムでは、スレッドがスリープする前に mutex または rw-lock を一定期間取得できるかどうかを継続的にチェックする方が効率的です。 mutex または rw-lock がこの期間中に使用可能になった場合、スレッドは同じタイムスライスですぐに続行できます。 ただし、相互排他ロックや rw-lock などの共有オブジェクトを複数のスレッドで頻繁にポーリングすると、「cache ping pong」 が発生する可能性があり、その結果プロセッサは互いの一部を無効にします。 InnoDB
では、ポーリング間のランダムな遅延を強制してポーリングアクティビティを非同期化することで、この問題を最小限に抑えます。 ランダム遅延はスピン待機ループとして実装されます。
スピン待機ループの継続時間は、ループ内で発生する PAUSE 命令の数によって決まります。 その数値を生成するには、0 から innodb_spin_wait_delay
値までの整数をランダムに選択し、その値に 50 を掛けます。 (乗数値 50 は、MySQL 8.0.16 の前にハードコードされ、その後構成できます。) たとえば、innodb_spin_wait_delay
設定が 6 の場合、整数は次の範囲からランダムに選択されます:
{0,1,2,3,4,5}
選択した整数に 50 が乗算されるため、PAUSE 命令の値は 6 つのいずれかになります:
{0,50,100,150,200,250}
この値セットの場合、250 はスピン待機ループで発生する PAUSE 命令の最大数です。 innodb_spin_wait_delay
を 5 に設定すると、使用可能な 5 つの値の {0,50,100,150,200}
のセットになります。200 は PAUSE 命令の最大数などです。 このように、innodb_spin_wait_delay
設定はスピンロックポーリング間の最大遅延を制御します。
すべてのプロセッサコアが高速なキャッシュメモリーを共有するシステムでは、この最大の遅延を短くするか、または innodb_spin_wait_delay=0
を設定してビジーループを完全に無効にすることができます。 複数のプロセッサチップを備えたシステムでは、キャッシュを無効にすると重大な影響を与える場合があるため、最大の遅延を増やすことができます。
100MHz Pentium 紀元では、innodb_spin_wait_delay
ユニットはマイクロ秒に相当するように調整されました。 この時間等価は保持されませんでしたが、PAUSE 命令が比較的長いプロセッサの Skylake 生成が導入されるまで、ほかの CPU 命令と比較してプロセッササイクルの観点から PAUSE 命令の期間はかなり一定のままでした。 innodb_spin_wait_pause_multiplier
変数は、PAUSE 命令の期間の違いを説明する方法を提供するために、MySQL 8.0.16 で導入されました。
innodb_spin_wait_pause_multiplier
変数は、PAUSE 命令の値のサイズを制御します。 たとえば、innodb_spin_wait_delay
設定が 6 の場合、innodb_spin_wait_pause_multiplier
値を 50 (デフォルトおよび以前にハードコードされた値) から 5 に減らすと、小さい PAUSE 命令値のセットが生成されます:
{0,5,10,15,20,25}
PAUSE 命令の値を増減できるため、プロセッサアーキテクチャーごとに InnoDB
を微調整できます。 たとえば、PAUSE 命令の値が小さいほど、PAUSE 命令が比較的長いプロセッサアーキテクチャーに適しています。
innodb_spin_wait_delay
および innodb_spin_wait_pause_multiplier
変数は動的です。 これらは、MySQL オプションファイルで指定することも、SET GLOBAL
ステートメントを使用して実行時に変更することもできます。 実行時に変数を変更するには、グローバルシステム変数を設定するのに十分な権限が必要です。 セクション5.1.9.1「システム変数権限」を参照してください。