17.8.8 配置自旋锁轮询
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是spin-wait循环中可以出现的最大PAUSE指令数。设置innodb_spin_wait_delay
为5将生成五个可能值{0,50,100,150,200}
innodb_spin_wait_delay
设置控制spin锁poll之间的最大延迟。
在所有处理器核心共享快速缓存内存的系统上,您可能通过设置
innodb_spin_wait_delay=0
减少最大延迟或禁用忙循环。在多处理器芯片系统上,缓存无效化的影响可能更为明显,您可能需要增加最大延迟。
在100MHz Pentium时代,
innodb_spin_wait_delay
单位被校准为等于1微秒。那时的时间等效性不再有效,但PAUSE指令的持续时间相对其他CPU指令仍然保持较为稳定,直到Skylake处理器generation的引入,这些处理器具有相对较长的PAUSE指令。innodb_spin_wait_pause_multiplier
变量提供了一种方式来-account for 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节,“系统变量权限”。