关于performance:第37问自旋锁-旋着旋着人就糊涂了

32次阅读

共计 1304 个字符,预计需要花费 4 分钟才能阅读完成。

问题

谋求 MySQL 的性能时,总据说要调整自旋锁的参数: innodb_spin_wait_delay 和 innodb_sync_spin_loops,是真的么?

试验

首先咱们要晓得自旋锁的长处:自旋锁要上锁时,如果须要期待其余线程开释锁,那么:

  • 在期待锁的过程中会先线程会先自旋一段时间

    • 自旋阶段,线程不会放弃 CPU
  • 自旋过后:

    • 如果能够获取锁了,那么响应会比拟快(自旋没产生上下文切换)
    • 如果还须要期待锁,再用更高老本的形式进行锁期待

innodb_spin_wait_delay 参数决定了自旋阶段的长度。当初咱们试着调整 innodb_spin_wait_delay 参数,来测试一下:

先宽油起一个数据库,此处疏忽步骤

建个表,放点数据:

配置好 performance_schema:

检查一下相干参数:

清理 performance_schema 的统计值:

来点压力:

查问一下锁期待老本最高的锁:

能够看到锁期待老本最高的是 lock_mutex,是爱护 MySQL 锁零碎的锁

上面咱们来调整一下 innodb_spin_wait_delay,让自旋的工夫变长:

重做一次压力(记得先清理统计数据),查看统计数据:

能够看到 lock_mutex 的均匀等待时间从 751267 减少到了 1399041。咱们让自旋阶段减少了 10 倍,锁期待的工夫也会随之增大。

目前的试验看上去自旋阶段越短越好,那么自旋阶段是不是就没有意义了?当然不会。

大家能够将 innodb_spin_wait_delay 设置为 1,再进行测试,随着自旋阶段的缩小,锁期待的工夫也会随之增大(大部分锁都应用了高老本的形式来进行期待)。

那么如何抉择自旋的参数呢?咱们倡议“不出问题不瞎调”。

在之前的统计数据中,工夫的单位是:cycle,依据以下换算表,锁的均匀工夫是 1399041 cycle,大略也就 0.5ms(1399041 / 2385353233 = 0.00058 s),占 SQL 的整体工夫很低,能够不必瞎调。

一个驰名的 CPU 问题

自旋阶段,MySQL 会调用 CPU 的 PAUSE 指令,既能占用了 CPU,同时 PAUSE 指令(比起其余占用 CPU 的指令)也比拟节能。

不过既然占用了 CPU,那么就会体现在 CPU 的使用率上。

当初咱们将 innodb_spin_wait_delay 再放大一点比拟一下:

能够看到 CPU 使用率会随着自旋阶段变长而升高

Intel 的 Skylake 系列 CPU,调大了 PAUSE 指令的周期时长。从 10 cycles 调大到 140 cycles(兴许是因为让 PAUSE 周期变长更有利于节能)

相似于明天的试验,这个指令的调整相当于拉长了自旋阶段。

这就导致了在 Skylake 系列 CPU 下,MySQL 的锁体现和 CPU 占用率体现都有可能更蹩脚。

(举荐文章:https://tech.meituan.com/2020…

小贴士

看到这里大家是不是开始焦虑了,要筹备换 CPU 了?

其实不用焦虑,绝大部分状况下,大家不必谋求极致的性能。比起榨取服务器的一点点极限性能,业务略微调整一下 SQL 获得的收益会 大几个数量级。

俗话说:业务写得好,运维回家早。


对于 MySQL 的技术内容,你们还有什么想晓得的吗?连忙留言通知小编吧!

正文完
 0