events_waits_current默认为空是因为instrument和consumer均未启用;必须执行update performance_schema.setup_consumers set enabled='yes' where name='events_waits_current'及update performance_schema.setup_instruments set enabled='yes' where name like 'wait/%',且timed也需为yes才能记录timer_wait。

直接查 events_waits_current 通常返回空——因为默认根本没开采集,不是你SQL写错了。
为什么 events_waits_current 查不到等待事件
MySQL 8.0 默认关闭等待事件采集链:instrument(埋点)和 consumer(写入表)都处于 DISABLED 状态。哪怕线程真卡在 wait/lock/metadata/sql/mdl,这张表也什么都不会有。
必须手动启用两处:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_waits_current';UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'wait/%';
注意:setup_instruments 里还有 timed 字段,它也得是 YES 才会记录耗时;如果只开 ENABLED 但 timed = NO,TIMER_WAIT 列会是 NULL。
查当前线程在等什么:用 THREAD_ID 关联 threads 表
别依赖 SHOW PROCESSLIST 的 ID 直接去查——PROCESSLIST_ID 和 THREAD_ID 不总是一一对应,尤其对后台线程(如 thread/sql/compress_gtid_table)或刚创建就阻塞的线程,PROCESSLIST_ID 可能为 NULL。
正确姿势是先从 threads 定位目标线程:
- 找活跃业务线程:
SELECT THREAD_ID, PROCESSLIST_ID, PROCESSLIST_INFO FROM performance_schema.threads WHERE PROCESSLIST_ID IS NOT NULL AND PROCESSLIST_STATE != 'idle'; - 再查它的等待:
SELECT EVENT_NAME, TIMER_WAIT, OBJECT_NAME, INDEX_NAME FROM performance_schema.events_waits_current WHERE THREAD_ID = 123 AND STATE = 'WAITING';
TIMER_WAIT 是皮秒单位(数值很大),若为 NULL,说明该线程此刻没在等待,正在执行中;若长期非空且稳定不降,基本就是卡死了。
判断瓶颈类型:看 events_waits_summary_global_by_event_name 而不是单条记录
盯着某一个线程的 EVENT_NAME 容易误判。真正拖垮系统的,往往是高频、中低延迟但持续累积的等待,比如:
-
wait/io/file/innodb/innodb_data_file:磁盘IO慢,或 buffer pool 太小被迫频繁刷脏页 -
wait/synch/mutex/innodb/buf_pool_mutex:缓冲池争用,常见于高并发简单查询 -
wait/lock/innoDB/row_lock:行锁冲突,但需结合data_locks看具体哪行被锁 -
wait/io/socket/sql/client_connection进前五?大概率是网络抖动或认证层卡住,不是数据库问题
执行:SELECT EVENT_NAME, COUNT_STAR, SUM_TIMER_WAIT FROM performance_schema.events_waits_summary_global_by_event_name ORDER BY SUM_TIMER_WAIT DESC LIMIT 5; ——重点看 SUM_TIMER_WAIT,不是 COUNT_STAR。
区分“真慢”和“假堵”:IO类等待必须交叉验证
看到一堆 wait/io/file/... 别急着换SSD。可能是语句设计问题(例如没走索引导致全表扫描读大量页),也可能是日志文件写满、innodb_log_file_size 设置过小引发频繁 checkpoint。
实操要联查:
- 查具体文件IO分布:
SELECT FILE_NAME, COUNT_READ, SUM_NUMBER_OF_BYTES_READ, COUNT_WRITE, SUM_NUMBER_OF_BYTES_WRITE FROM performance_schema.file_summary_by_event_name WHERE EVENT_NAME LIKE 'wait/io/file/%' ORDER BY SUM_NUMBER_OF_BYTES_WRITE DESC LIMIT 3; - 再看是不是集中在
ib_logfile0或mysql-bin.000xxx上——那就不是数据文件问题,而是日志配置或归档策略需要调整
performance_schema 的价值不在“看到等待”,而在“把等待和具体资源、线程、SQL 串成一条可回溯的证据链”。漏掉 threads 表这环,就只剩碎片;忽略 timed 字段,所有耗时字段都是摆设。











