先查performance_schema.events_waits_summary_global_by_event_name中sum_timer_wait最高的等待事件,它是性能瓶颈最直接信号源;再结合threads与events_waits_current定位具体线程卡点,最后用file_summary_by_event_name等表交叉验证io类等待真伪。

查全局等待事件热点,先看哪个event_name最耗时
等待事件是性能瓶颈最直接的信号源。别一上来就翻 events_waits_current,它只反映“此刻”卡在哪,而真正拖垮系统的往往是高频、中低延迟但持续累积的等待类型。
实操建议:
- 执行
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 10,重点关注SUM_TIMER_WAIT(单位皮秒),不是COUNT_STAR - 常见高耗时 event_name:
wait/io/file/innodb/innodb_data_file(磁盘读写慢)、wait/synch/mutex/innodb/buf_pool_mutex(缓冲池争用)、wait/lock/innoDB/row_lock(行锁冲突) - 如果
wait/io/socket/sql/client_connection排进前五,说明大量连接卡在建立阶段,大概率是网络或认证层问题,不是数据库本身瓶颈
定位具体线程卡在哪,用threads+events_waits_current联查
performance_schema.threads 是唯一能覆盖全生命周期的线程入口,比 SHOW PROCESSLIST 更可靠——它不会漏掉刚启动就阻塞的线程,也不会丢掉已断连但未清理的“僵尸”状态。
实操建议:
- 先找 SQL 线程:
SELECT THREAD_ID, NAME, PROCESSLIST_ID FROM performance_schema.threads WHERE NAME LIKE '%slave_sql%' OR (PROCESSLIST_ID IS NOT NULL AND PROCESSLIST_STATE != 'idle') - 再查该线程当前等待:
SELECT EVENT_NAME, TIMER_WAIT, SOURCE FROM performance_schema.events_waits_current WHERE THREAD_ID = ?(? 替换为上一步的 THREAD_ID) - 注意
TIMER_WAIT为NULL表示线程当前未等待,而是正在执行;若长期为非空且值稳定,说明被卡死,不是临时抖动
区分IO类等待是真慢还是假堵
看到大量 wait/io/file/... 不代表磁盘坏了,可能是语句设计导致频繁小IO、或 buffer pool 太小被迫刷脏页、甚至只是日志文件写满。
实操建议:
- 结合
file_summary_by_event_name查具体文件: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 5 - 若
ib_logfile0或ibdata1占比异常高,检查innodb_log_file_size和innodb_buffer_pool_size配置 - 对比
innodb_buffer_pool_reads和innodb_buffer_pool_read_requests:命中率低于 95% 就该怀疑是缓存不足引发的“伪IO瓶颈”
旧版本MySQL看不到复制SQL的等待?得换表查
MySQL 8.0.26 之前,slave_sql 线程的语句压根不进 events_statements_* 表,你查 events_waits_current 只能看到等待事件,却不知道它在等哪条语句。
实操建议:
- 优先查
replication_applier_status_by_worker(5.7+)或replication_applier_status(5.6),看LAST_APPLIED_TRANSACTION和APPLYING_TRANSACTION字段,确认是否积压 - 用
events_waits_current找到 SQL 线程的THREAD_ID后,再查events_stages_current:SELECT EVENT_NAME, TIMER_WAIT FROM performance_schema.events_stages_current WHERE THREAD_ID = ? ORDER BY TIMER_START DESC LIMIT 1,阶段名如stage/sql/insert或stage/innodb/alter table end能反推操作类型 - 别依赖
DIGEST_TEXT——老版本里它对复制线程永远是NULL
Seconds_Behind_Master = 0 时,events_waits_current 里可能已经堆着十几个 wait/synch/mutex/innodb/trx_sys_mutex ——这说明事务系统锁早被撑满,只是还没来得及反映到延迟指标上。











