14.8.9 配置自旋锁轮询

InnoDB mutexesrw-locks通常保留较短的时间间隔。在多核系统上,线程在睡眠之前的一段时间内连续检查是否可以获取互斥或 rw-lock 可能会更有效率。如果在此期间互斥锁或 rw-lock 可用,则线程可以在同一时间片中立即 continue。但是,通过多个线程对共享对象(例如互斥锁或 rw-lock)进行太频繁的轮询会导致“高速缓存乒乓”,这导致处理器使彼此的高速缓存部分无效。 InnoDB通过在轮询之间强制随机延迟以使轮询活动不同步来最大程度地减少此问题。随机延迟被实现为旋转 await 循环。

旋转 await 循环的持续时间取决于循环中发生的 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}

对于该组值,旋转 await 循环中可能出现的最大 PAUSE 指令数为 250. innodb_spin_wait_delay设置为 5 会导致一组五个可能的值{0,50,100,150,200},其中 200 是 PAUSE 指令的最大数量,依此类推。这样,innodb_spin_wait_delay设置可控制自旋锁定轮询之间的最大延迟。

延迟循环的持续时间取决于 C 编译器和目标处理器。在 100MHz 奔腾时代,将innodb_spin_wait_delay单位校准为等于 1 微秒。那个时间上的等价性不成立,但是相对于大多数处理器体系结构上的其他 CPU 指令,暂停指令的持续时间在处理器周期方面一直保持相当恒定。

在所有处理器核心共享快速缓存的系统上,可以通过设置innodb_spin_wait_delay=0来减少最大延迟或完全禁用繁忙循环。在具有多个处理器芯片的系统上,缓存无效化的影响可能更大,并且可能会增加最大延迟。

innodb_spin_wait_delay变量是动态的。它可以在 MySQL 选项文件中指定,也可以在运行时使用SET GLOBAL语句进行修改。运行时修改需要足以设置全局系统变量的特权。参见第 5.1.8.1 节“系统变量特权”