InnoDB
互斥锁 和 读写锁 通常保留短时间间隔。在多核系统上,对于一个线程来说,在短时间内不断检查是否可以获取互斥锁或读写锁可能更高效。如果在这个时间段内互斥锁或读写锁变得可用,线程可以立即继续执行,不需要等待下一个时间片段。然而,多个线程频繁轮询共享对象(如互斥锁或读写锁)可能会导致 “缓存 ping pong”,从而导致处理器使对方的缓存失效。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 节,“系统变量权限”。