### 15.8.8 配置自旋锁轮询

[](<>)[](<>)[](<>)

`InnoDB` [互斥体](glossary.html#glos_mutex)和[rw锁](glossary.html#glos_rw_lock)通常为短时间间隔保留。在多核系统上，线程在休眠之前的一段时间内不断检查它是否可以获取互斥锁或读写锁会更有效率。如果在此期间互斥锁或 rw-lock 可用，则线程可以在同一时间片内立即继续。但是，多线程对共享对象（如互斥锁或 rw 锁）的过于频繁的轮询可能会导致“缓存乒乓”，从而导致处理器使彼此缓存的部分无效。`InnoDB`通过强制轮询之间的随机延迟以使轮询活动不同步，从而最大限度地减少此问题。随机延迟被实现为自旋等待循环。

自旋等待循环的持续时间由循环中出现的 PAUSE 指令的数量决定。该数字是通过随机选择一个从 0 到但不包括[`innodb_spin_wait_delay`](innodb-parameters.html#sysvar_innodb_spin_wait_delay)值，并将该值乘以 50。（乘数 50 在 MySQL 8.0.16 之前是硬编码的，之后可配置。）例如，从以下范围中随机选择一个整数作为innodb_spin_wait_delay[`设置为 6：`](innodb-parameters.html#sysvar_innodb_spin_wait_delay)选定的整数乘以 50，得到六个可能的 PAUSE 指令值之一：

```
{0,1,2,3,4,5}
```

对于这组值，250 是可在自旋等待循环中发生的 PAUSE 指令的最大数量。

```
{0,50,100,150,200,250}
```

一个innodb_spin_wait_delay[`设置为 5 会产生一组五个可能的值`](innodb-parameters.html#sysvar_innodb_spin_wait_delay){0,50,100,150,200}`，其中 200 是 PAUSE 指令的最大数量，依此类推。`这样，innodb_spin_wait_delay[`设置控制自旋锁轮询之间的最大延迟。`](innodb-parameters.html#sysvar_innodb_spin_wait_delay)在所有处理器内核共享快速缓存的系统上，您可以通过设置来减少最大延迟或完全禁用繁忙循环

innodb_spin_wait_delay=0[`.`](innodb-parameters.html#sysvar_innodb_spin_wait_delay)在具有多个处理器芯片的系统上，缓存失效的影响可能更为显着，您可能会增加最大延迟。

在 100MHz Pentium 时代，一个[`innodb_spin_wait_delay`](innodb-parameters.html#sysvar_innodb_spin_wait_delay)单位被校准为相当于一微秒。这种时间等价性并不成立，但在处理器周期方面，PAUSE 指令持续时间相对于其他 CPU 指令保持相当恒定，直到引入具有相对较长 PAUSE 指令的 Skylake 一代处理器。这[`innodb_spin_wait_pause_multiplier`](innodb-parameters.html#sysvar_innodb_spin_wait_pause_multiplier)在 MySQL 8.0.16 中引入了变量，以提供一种方法来解释 PAUSE 指令持续时间的差异。

这[`innodb_spin_wait_pause_multiplier`](innodb-parameters.html#sysvar_innodb_spin_wait_pause_multiplier)变量控制 PAUSE 指令值的大小。例如，假设一个[`innodb_spin_wait_delay`](innodb-parameters.html#sysvar_innodb_spin_wait_delay)设置为 6，减少[`innodb_spin_wait_pause_multiplier`](innodb-parameters.html#sysvar_innodb_spin_wait_pause_multiplier)从 50（默认值和以前硬编码的值）到 5 的值会生成一组较小的 PAUSE 指令值：

```
{0,5,10,15,20,25}
```

增加或减少 PAUSE 指令值的能力允许微调`InnoDB`针对不同的处理器架构。例如，较小的 PAUSE 指令值适用于具有相对较长 PAUSE 指令的处理器架构。

这[`innodb_spin_wait_delay`](innodb-parameters.html#sysvar_innodb_spin_wait_delay)和[`innodb_spin_wait_pause_multiplier`](innodb-parameters.html#sysvar_innodb_spin_wait_pause_multiplier)变量是动态的。它们可以在 MySQL 选项文件中指定或在运行时使用[`设置全球`](set-variable.html)陈述。在运行时修改变量需要足够的权限来设置全局系统变量。看[第 5.1.9.1 节，“系统变量权限”](system-variable-privileges.html).
