InnoDB
互斥鎖和讀寫鎖通常保留用於短時間間隔。在多核心系統上,對於執行緒來說,在休眠之前,持續檢查是否可以在一段時間內取得互斥鎖或讀寫鎖可能會更有效率。如果互斥鎖或讀寫鎖在此期間變成可用,則執行緒可以立即在相同的時間分片中繼續。但是,多個執行緒過於頻繁地輪詢共用物件 (例如互斥鎖或讀寫鎖) 會導致 「快取乒乓」,這會導致處理器彼此之間的快取部分失效。InnoDB
通過強制在輪詢之間產生隨機延遲以取消同步輪詢活動來最大限度地減少此問題。隨機延遲會實作為自旋等待迴圈。
自旋等待迴圈的持續時間由迴圈中發生的 PAUSE 指令數決定。該數字是透過隨機選取一個從 0 到但不包括 innodb_spin_wait_delay
值的整數,並將該值乘以 50 來產生。例如,針對 innodb_spin_wait_delay
設定為 6 時,會從以下範圍中隨機選取一個整數
{0,1,2,3,4,5}
選取的整數乘以 50,會產生六個可能的 PAUSE 指令值之一
{0,50,100,150,200,250}
對於該值集,250 是自旋等待迴圈中可能發生的最大 PAUSE 指令數。innodb_spin_wait_delay
設定為 5 會產生一組五個可能的值 {0,50,100,150,200}
,其中 200 是最大 PAUSE 指令數,依此類推。透過這種方式,innodb_spin_wait_delay
設定會控制自旋鎖輪詢之間的最大延遲。
在所有處理器核心共用快速快取記憶體的系統上,您可以透過設定 innodb_spin_wait_delay=0
來減少最大延遲或完全停用忙碌迴圈。在具有多個處理器晶片的系統上,快取失效的影響可能更為顯著,您可以增加最大延遲。
在 100MHz Pentium 時代,innodb_spin_wait_delay
單位校準為相當於一微秒。該時間等效性不成立,但 PAUSE 指令持續時間在處理器週期方面相對於其他 CPU 指令保持相當恆定,直到推出 Skylake 世代處理器,其具有相對較長的 PAUSE 指令。innodb_spin_wait_pause_multiplier
變數提供了一種考慮 PAUSE 指令持續時間差異的方法。
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
語句進行修改。在執行時修改這些變數需要足夠的權限來設定全域系統變數。請參閱 第 7.1.9.1 節,「系統變數權限」。