mysql 8.0升级后查询变慢主因是sys.innodb_lock_waits视图行为变更引发隐式mdl阻塞:5.7中为无锁纯视图,8.0底层依赖performance_schema.data_lock_waits等表,读取时主动申请mdl锁,若恰逢ddl执行,监控脚本即卡在“waiting for table metadata lock”,拖慢连接池并加剧业务sql延迟。

MySQL 8.0 升级后查询变慢,大概率不是“性能退化”,而是配置、行为或依赖项不兼容导致的隐性阻塞——直接调 buffer pool 或加索引往往无效,甚至让问题更隐蔽。
为什么 sys.innodb_lock_waits 会拖垮业务查询
升级后监控脚本还在跑老写法,比如每分钟执行:
SELECT * FROM sys.innodb_lock_waits;
这条语句在 5.7 是查 information_schema 的几个表,开销小;但在 8.0 中,sys.innodb_lock_waits 底层改成了 JOIN performance_schema.data_lock_waits 和 information_schema.INNODB_TRX,而 data_lock_waits 是一个实时采集锁等待关系的动态视图,高并发下可能触发行级锁争用或元数据锁(MDL)阻塞。
- 现象:业务 SQL 突然变慢,但 CPU、IO、连接数都正常,
SHOW PROCESSLIST里能看到大量Sending data状态卡住 - 验证方式:临时停掉监控脚本,观察慢查询是否消失;或手动执行该语句看耗时是否 >1s
- 修复建议:改用轻量替代方案,例如只查
performance_schema.events_statements_current中STATEMENT含LOCK的记录,或用SELECT * FROM performance_schema.data_locks LIMIT 10快速采样
EXPLAIN FORMAT=TREE 比传统输出更能暴露真实瓶颈
老习惯只看 type 和 key 列,容易误判。8.0 的 FORMAT=TREE 直接展示嵌套执行顺序和代价估算,对 JOIN、子查询、窗口函数特别有用。
- 关键信号:
-> Filter: ... (cost=...)行里 cost 明显高于其他分支,说明过滤逻辑没下推到索引层 - 常见陷阱:WHERE 中对字段用了函数(如
DATE(created_at) = '2026-09-28'),FORMAT=TREE会显示 “Using where” 且 cost 飙升,而传统EXPLAIN可能只显示type=range让你误以为走了索引 - 实操建议:对慢 SQL 执行
EXPLAIN FORMAT=TREE SELECT ...,重点关注最外层 cost 值是否远超预估扫描行数 × 单行成本(通常单行基础 cost ≈ 1.0)
慢查询日志默认关闭 + log_output=TABLE 是最稳的开启方式
8.0 默认 slow_query_log = OFF,且旧版靠 SET GLOBAL slow_query_log = ON 临时开启的方式,在云 RDS 上常被禁用,导致你根本看不到慢 SQL。
- 必须改配置文件:
slow_query_log = ON、long_query_time = 1.0(支持小数)、log_output = 'TABLE' - 好处:日志写入
mysql.slow_log表,可直接SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10查,字段含sql_text、query_time、rows_examined,比解析文本日志可靠得多 - 注意点:
log_output = 'TABLE'会略微增加写入开销,但远小于FILE模式下mysqldumpslow解析失败或漏字段的风险
query_cache_type 参数会导致启动失败,但残留配置可能引发连锁误判
8.0 彻底移除了查询缓存,如果 my.cnf 里还留着 query_cache_type=0 或 query_cache_size=0,MySQL 启动会直接报错:
Unknown variable 'query_cache_type=0'
但更危险的是:有人删了这行,却忘了删掉配套的 query_cache_limit、query_cache_min_res_unit —— 这些参数同样不存在,启动仍失败,排查时容易只盯第一个报错忽略后续。
- 检查命令:
mysqld --defaults-file=/etc/my.cnf --verbose --help | grep query,确认无任何 query_cache 相关输出 - 连带影响:若启动失败后强行用跳过配置的方式启动(如
mysqld --skip-grant-tables),可能导致performance_schema未启用,进而使EXPLAIN FORMAT=TREE不可用、data_lock_waits视图为空 - 建议动作:升级前用
mysqld --validate-config校验配置文件,比等启动失败再排查快得多
真正卡住升级后查询的,往往不是大表扫描,而是那些“看起来很轻”的元数据操作、被忽略的配置残留、或者旧监控脚本与新视图机制的冲突——这些地方不显眼,但一触发就是全局毛刺。











