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 节,“系统变量权限”。