经过两次优化后,mysql 的单个连接 tps 如下:
通过第二轮优化,性能提升到了原来的 12.18 倍(1924 / 158 ≈ 12.18)。接下来我们详细探讨这两次优化的过程。
书接上回
上次我们通过 Linux 内核的 ebpf 模块的观测能力,成功定位了 MySQL 的瓶颈,并通过调整相应的 MySQL 参数,将 tps 从 158 提升到了 1673。然而,从性能角度来看,我们仍有提升空间。
我们继续按照既定方法论,先从整体上把握 Linux 的资源使用情况。
mpstat 1 30 Linux 5.14.0-55.el9.x86_64 (git-sqlpy-com) 07/21/2022 _x86_64_ (2 CPU) 01:30:15 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 01:30:16 AM all 37.63 0.00 7.73 11.86 0.00 3.09 0.00 0.00 0.00 39.69 01:30:17 AM all 38.38 0.00 7.07 14.65 0.00 3.03 0.00 0.00 0.00 36.87 01:30:18 AM all 38.34 0.00 7.77 12.44 0.00 3.11 0.00 0.00 0.00 38.34 01:30:19 AM all 36.04 0.00 6.09 13.20 0.00 3.05 0.00 0.00 0.00 41.62
可以看出,IO-WAIT 仅有 10% 左右,说明 IO 负载并不高;但 CPU 的用户态使用率接近 40%,这相对于 IO 来说较高,整体资源使用并不均衡。
分析问题
从上次优化后的资源使用情况(IO-WAIT 较低)可以得出,如果有必要,我们可以通过增加 IO 资源来降低 CPU 资源的使用(IO 为 10%,CPU 为 40%)。当然,最终是否有必要还需数据支持。幸运的是,上次优化后的火焰图仍然可用,它可以提供我们所需的数据。

binlog_cache_data::compress 这个压缩 BIN-LOG 的函数占用了 10.28% 的 CPU 资源。考虑到 BIN-LOG 是顺序 IO,且目前 IO 不是瓶颈,为了节省 CPU 资源,我们决定“优化”掉压缩功能。这样,我们打算通过增加 IO 资源来换取 CPU 资源,从而打造一个更加均衡的系统。
调整参数验证性能
由于我们的目标是提升性能,压缩 BIN-LOG 在此目标下是没有意义的。因此,我们调整 MySQL 参数,关闭 BIN-LOG 压缩,避免 CPU 执行无意义的任务。
mysql> set @@global.binlog_transaction_compression = OFF; Query OK, 0 rows affected (0.00 sec)
接下来,我们测试性能:
mtls-auto-fill --host=127.0.0.1 --port=3306 --user=root --password=xxx --database=tempdb --table=t --rows=50000 execute Report: ------------------------------------ |tps = 1924.565426390742 |cost_time = 25.979891 ------------------------------------ Compelete.
然后,我们绘制火焰图以查看优化后的效果:
# 这里直接用的 ebpf 生态的工具 profile -p 537985 -af 11 --stack-storage-size=163840 > /tmp/simple-insert-double-zero-binlog-not-compression.out

trans_commit 原本是一个双峰结构,右边的峰是由于压缩 BIN-LOG 导致的,占用约 10.28% 的 CPU。经过我们的参数调整,这部分消耗已被消除。
此外,最左边的 syscall 峰也消失了(目前还无法确定其具体作用,但以后会进一步分析),它在未优化前大约占用 5% 的 CPU。
根据这两组数据,我们可以从火焰图大致推算出 CPU 优化的收益。一个是 10%,另一个是 5%,总的性能大致提升了 115%。我们现在可以估算性能提升:
In [1]: 1673 * 1.15 Out[1]: 1923.949
我们的实测值为 1924.565,与估算值非常接近。
还有没有油水
关于是否还有进一步优化的空间,我们可以通过观察系统资源使用情况来判断。
mpstat 1 30 Linux 5.14.0-55.el9.x86_64 (git-sqlpy-com) 07/29/2022 _x86_64_ (2 CPU) 00:42:06 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 00:42:07 AM all 32.16 0.00 9.55 17.59 0.00 3.02 0.00 0.00 0.00 37.69 00:42:08 AM all 34.54 0.00 10.31 18.04 0.00 3.09 0.00 0.00 0.00 34.02 00:42:09 AM all 36.18 0.00 8.54 18.59 0.00 3.52 0.00 0.00 0.00 33.17 00:42:10 AM all 34.85 0.00 9.60 19.70 0.00 2.53 0.00 0.00 0.00 33.33 00:42:11 AM all 33.85 0.00 9.74 21.54 0.00 4.10 0.00 0.00 0.00 30.77
可以看到,参数调整后,用户态 CPU 使用率从之前的 40% 左右下降到了 34% 左右,而 IO-WAIT 从 10% 左右上升到了 20%。也就是说,整个系统从 40:10 的结构调整到了 34:20 的结构,变得更加均衡。
我们再来看一下 IO-WAIT 上升 100% 的原因(从 10% 上升到 20%,上升了 100%)。
funccount -i 1 -p 111659 'vfs_*' FUNC COUNT b'vfs_fsync_range' 496 b'vfs_write' 6159 b'vfs_read' 8373
可以看到,sync 和 write 的比例关系发生了变化,由之前的 292:7009 变成了现在的 496:6159。
因此,还有优化的空间,请分享这篇文章,说不定更新速度会更快哦!
以上就是第二轮:从 Linux 内核事件看 MySQL 性能瓶颈的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号