Performance Schema默认开启但关键采集项关闭,需手动启用instruments、consumers和actors才能获取慢SQL及锁等待等监控数据。

Performance Schema 不是“开了就能用”的监控开关,它默认开启但多数关键采集项处于关闭状态——直接查 events_statements_summary_by_digest 却返回空或只有极少量数据,基本都是因为没启用对应消费者或 instruments。
为什么查不到慢 SQL?先确认这三件事
很多用户执行 SELECT * FROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC LIMIT 5; 却发现耗时最高的 SQL 总是 SELECT ... FROM events_statements_summary_by_digest 自身,根本看不到业务 SQL。这不是 bug,而是配置缺失:
-
performance_schema变量值为ON仅表示引擎加载成功,不代表事件采集已启动 - 必须显式启用语句类采集器:
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'statement/sql/%'; - 必须启用对应消费者表:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('events_statements_current', 'events_statements_history', 'events_statements_summary_by_digest'); - MySQL 8.0+ 默认禁用
history行为,若需查历史执行详情(如某条 SQL 的锁等待、扫描行数),还需在setup_actors中为指定用户/主机开启:UPDATE performance_schema.setup_actors SET HISTORY = 'YES' WHERE USER = 'your_app_user';
查最耗时的 SQL:别只看总时间,要看 avg 和 rows_examined
events_statements_summary_by_digest 是性能分析的起点,但光排序 SUM_TIMER_WAIT 容易误判。一条每秒执行 1000 次、单次 2ms 的 SQL,总耗时可能远超一条每天跑一次、耗时 5s 的报表 SQL——后者更该优先优化。
- 优先关注
AVG_TIMER_WAIT / 1e9(单位秒):> 100ms 的查询大概率需要索引或改写 - 结合
ROWS_EXAMINED和ROWS_SENT:若前者是后者的百倍以上,说明大量数据被扫描却未返回,典型如缺少 WHERE 条件或索引失效 -
DIGEST_TEXT是归一化后的模板(如SELECT * FROM users WHERE id = ?),能帮你识别同一类问题 SQL,避免被参数干扰 - 注意:该表默认只保留前 10000 个 digest,高频短 SQL 可能被挤出,需配合
events_statements_history抓取实时片段
定位锁等待瓶颈:用 data_lock_waits 连通“谁在等谁”
当应用出现间歇性卡顿、事务超时,但没触发死锁日志时,information_schema.INNODB_LOCK_WAITS 在 MySQL 8.0 已废弃,且只能看到最后一条锁链;真正可用的是 Performance Schema 的锁事件闭环。
- 先查正在发生的等待:
SELECT * FROM performance_schema.data_lock_waits;—— 返回WAITING_TRX_ID和BLOCKING_TRX_ID - 关联持锁者行为:
SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_current WHERE THREAD_ID IN (SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID IN (SELECT BLOCKING_PID FROM performance_schema.data_lock_waits)); - 关键字段:
OBJECT_NAME(哪张表)、INDEX_NAME(哪个索引)、LOCK_DATA(具体锁住哪一行,如123或supremum pseudo-record)——后者说明是间隙锁,可能引发幻读 - ⚠️ 注意:
data_locks表默认不启用,需提前打开:UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME = 'wait/lock/metadata/sql_lock';
排查 I/O 或 CPU 瓶颈:从等待事件反推资源热点
当 SHOW PROCESSLIST 里大量线程状态为 Waiting for table level lock 或 Writing to net,说明瓶颈不在 SQL 本身,而在底层资源。
- 查最耗时的等待类型:
SELECT EVENT_NAME, COUNT_STAR, SUM_TIMER_WAIT/1e9 AS total_sec FROM performance_schema.events_waits_summary_global_by_event_name WHERE SUM_TIMER_WAIT > 0 ORDER BY SUM_TIMER_WAIT DESC LIMIT 5; - 常见高危项:
wait/io/file/innodb/innodb_data_file(磁盘读写慢)、wait/synch/mutex/innodb/buf_pool_mutex(Buffer Pool 争用)、wait/io/socket/sql/client_connection(网络或连接池打满) - 若
wait/synch/cond/sql/MYSQL_RELAY_LOG::update_cond高,说明主从延迟严重;若wait/lock/metadata/sql_lock频繁,可能是 DDL 操作阻塞了 DML - ⚠️ 所有 timer 值单位是皮秒(picosecond),务必除以
1e9转为秒,否则数值大到无法理解
Performance Schema 的真实难点不在语法,而在于事件采集的“漏斗式”控制:instruments → consumers → actors → history tables,任一环节关闭都会导致数据断层。线上环境建议只开 events_statements_summary_by_digest 和 data_lock_waits,避免全量采集带来的性能抖动;临时排查时再按需打开细粒度采集,并记得事后关掉。



















