mysql 8.0在高并发读写混合场景下吞吐更高,核心是锁调度与group commit优化更激进:重构锁等待唤醒逻辑、共享redo buffer和fsync资源,提升小事务写入密度与日志攒批能力。

高并发下锁调度与Group Commit优化更激进
MySQL 8.0 的 InnoDB 在高并发读写混合(如 oltp_read_write)中能维持更高吞吐,核心不是“单次操作更快”,而是“单位时间能安全处理更多事务”。它重构了锁等待队列的唤醒逻辑和日志刷盘路径,让多个事务更高效地共享 redo log buffer 和 fsync 资源。
-
innodb_log_write_ahead_size默认值从 5.7 的 8192 提升到 8.0 的 4096,减小写放大,提升小事务写入密度 - Group commit 的窗口更宽松:8.0 允许更长的等待时间(受
innodb_log_wait_for_flush_spin_hwm控制)来攒更多事务一起刷盘,5.7 则更早放弃等待、单独提交 - 间隙锁(Gap Lock)在二级索引上的判断更精准,减少误锁;但代价是加锁路径变长——所以在低并发(1–8线程)时反而略慢
缓冲池 LRU 与预加载机制真正起效
5.7 的 innodb_buffer_pool_load_at_startup 只恢复 page id 列表,不保证数据页内容热加载;8.0 的 innodb_buffer_pool_dump_pct + innodb_buffer_pool_load_at_startup 配合改进的 LRU 管理,能让重启后 30 秒内热点命中率快速回升至 90%+,避免冷启动抖动拖垮混合负载。
- 8.0 默认启用
innodb_buffer_pool_dump_at_shutdown=ON,且 dump 文件格式更紧凑、加载并行度更高 - LRU 链表拆分为 young/old 子链,并引入
innodb_old_blocks_time防止全表扫描污染 hot 区——这对混合场景里“偶发大查询 + 主流点查”特别关键 - 注意:若未显式配置
innodb_buffer_pool_instances(如设为 8),高并发下 buffer pool mutex 争用反而会抵消优势
元数据访问不再拖累执行计划生成
5.7 中每次 SELECT 执行前都要打开 .frm 文件读结构,information_schema 查询慢如爬行;8.0 把所有表定义、列信息、统计信息都存在 InnoDB 表里,EXPLAIN 或 prepare 阶段的元数据检查快一个数量级——尤其当单次事务含多语句、或 ORM 自动生成大量 ad-hoc 查询时,这个开销差异会被放大。
- 8.0 的
information_schema_stats_expiry = 3600(默认)意味着统计信息缓存复用更久,避免频繁触发ANALYZE TABLE - 但副作用是:如果业务频繁增删列或分区,旧统计可能误导优化器;此时需手动
ANALYZE TABLE或调小该值 - 5.7 的
table_definition_cache容易在千表级实例中打满,导致句柄泄露;8.0 无此限制,但会悄悄多占 buffer pool 内存
默认配置差异常被忽略,却决定实测结果
直接跑 Sysbench 对比却不重置配置,等于拿 5.7 的宽松模式 vs 8.0 的严格模式比——结果必然失真。最常踩的坑是没关 performance_schema 或没清 persisted_variables。
- 8.0 默认开启
performance_schema全项采集,仅events_statements_history_long就吃掉 10MB+ 内存;测试前务必执行:UPDATE performance_schema.setup_consumers SET ENABLED = 'NO' WHERE NAME LIKE 'events_statements_%'; -
SET PERSIST sort_buffer_size = 2097152这类命令写入的配置,优先级高于my.cnf;升级后不RESET PERSIST,旧值可能持续生效,导致排序溢出 - 8.0 的
innodb_redo_log_encrypt=OFF是默认值,但 CRC 校验逻辑仍存在;SSD 场景下建议确认innodb_flush_neighbors=0已生效,否则随机写性能反降
SET PERSIST。











