MySQL 5.7在多数OLTP场景下实测性能仍优于8.0,尤其在“双1”强一致性配置下差距更明显;根本原因是8.0重构了持久化路径、锁调度和日志刷盘逻辑,导致高一致性要求下开销上升。

MySQL 5.7 在多数 OLTP 场景下实测性能仍优于 8.0,尤其在 sync_binlog=1 和 innodb_flush_log_at_trx_commit=1(即“双1”强一致性配置)下,差距更明显——这不是理论推测,而是多个独立测试环境(CentOS 7、Ubuntu 22、AWS EC2)反复验证的结果。
为什么 Sysbench 测试结果在 5.7 和 8.0 间不一致
根本原因不是“8.0 更慢”,而是它对持久化路径、锁调度和日志刷盘逻辑做了重构,导致在高一致性要求下开销上升。比如:
-
innodb_flush_log_at_trx_commit=1在 8.0 中触发更严格的 redo log fsync 链路,且与caching_sha2_password认证模块存在隐式协同开销(即使未显式启用 SSL,握手阶段也会引入额外系统调用) - 8.0 默认启用
innodb_redo_log_encrypt=OFF,但其 redo 日志写入路径增加了 CRC 校验与 buffer chain 锁竞争,小事务密集场景下易成为瓶颈 - 5.7 的查询优化器对简单 JOIN 和范围扫描更“保守稳定”,而 8.0 的新优化器(尤其是 CTE / 窗口函数路径)会为所有查询加载更多元数据检查逻辑,哪怕没用到这些特性
必须统一的关键 Sysbench 测试参数
否则对比毫无意义。以下参数在每次测试前必须显式重置并验证:
- 用
sysbench --db-driver=mysql --mysql-host=... --mysql-port=3306 --mysql-user=sbtest --mysql-password=sbtest --mysql-db=sbtest显式指定连接参数,避免读取 ~/.my.cnf 导致版本间配置漂移 - 测试前执行:
SET GLOBAL innodb_max_dirty_pages_pct = 90; SET GLOBAL innodb_flush_neighbors = 0;—— 8.0 默认值是 90,5.7 是 75;innodb_flush_neighbors在 SSD 环境下设为 0 才公平 - 每次测试前清空 OS cache:
echo 3 | sudo tee /proc/sys/vm/drop_caches,并重启 mysqld(不能只 flush tables) - 建表后务必运行
ANALYZE TABLE sbtest1;,否则 8.0 的统计信息收集机制可能滞后,影响执行计划稳定性
只读/只写/读写模式下最该盯住的指标
别只看平均 TPS,重点观察抖动和拐点:
-
只读模式(
oltp_read_only):5.7 通常比 8.0 高出 ~30%,尤其在 64+ 并发时,8.0 的performance_schema默认全开会拖累 CPU 缓存命中率;建议测试前关掉:UPDATE performance_schema.setup_consumers SET ENABLED = 'NO' WHERE NAME LIKE 'events_statements_%'; -
只写模式(
oltp_write_only):8.0 的 group commit 优化本应占优,但实测中因binlog_order_commits=ON(默认)与 InnoDB prepare 阶段耦合更深,反而在 120+ 线程时出现 TPS 断崖下跌 -
读写混合(
oltp_read_write):关注QPS而非 TPS,因为 8.0 的SELECT ... FOR UPDATE在行锁升级路径上新增了 latch 检查,短事务延迟波动更大
真正容易被忽略的是:MySQL 8.0 的性能“天花板”高度依赖 innodb_buffer_pool_instances 与 CPU 核心数的匹配。比如在 8 核机器上设成 8 是合理的,但在 4 核虚拟机里还设成 8,会导致 buffer pool mutex 争用加剧——这个细节连很多压测脚本都漏掉校验。











