可通过iostat、performance_schema及show processlist综合识别ddl引发的io飙升:当await>50ms且%util接近100%、mysqld io%持续高于70%、state显示copy to tmp table等,结合file_summary_by_event_name中innodb文件读写量突增,即可确认。

如何识别DDL正在引发IO飙升
DDL操作在MySQL 8.0中若采用COPY或部分INPLACE算法,会触发大量磁盘读写,表现为I/O等待陡增、iotop中mysqld进程IO%持续高于70%、系统平均负载(load average)异常跳升。这不是“慢查询”问题,而是底层数据搬移行为——尤其当表超过千万行时,ALTER TABLE ... ADD COLUMN(非INSTANT)、ENGINE=INNODB重整等操作极易触发。
- 执行
SHOW PROCESSLIST时看到State为copy to tmp table、renaming table或altering table,基本可确认是DDL在IO层施压 - 用
iostat -x 1观察%util和await:若await> 50ms 且%util接近100%,说明磁盘已饱和 - 检查
performance_schema.file_summary_by_event_name中wait/io/file/innodb/innodb_data_file的SUM_NUMBER_OF_BYTES_READ/WRITE是否在DDL期间突增数倍
用Performance Schema定位具体DDL语句和IO消耗
MySQL 8.0默认启用performance_schema,但需确保相关消费者已开启。仅靠SHOW PROCESSLIST看不到IO细节,必须查表:
- 先确认关键消费者已启用:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('events_statements_current', 'events_waits_current', 'file_summary_by_event_name'); - 查正在执行的DDL及其IO开销:
SELECT p.THREAD_ID, p.SQL_TEXT, f.COUNT_READ, f.SUM_NUMBER_OF_BYTES_READ, f.COUNT_WRITE, f.SUM_NUMBER_OF_BYTES_WRITE FROM performance_schema.events_statements_current p JOIN performance_schema.threads t ON p.THREAD_ID = t.THREAD_ID JOIN performance_schema.file_summary_by_event_name f ON f.EVENT_NAME LIKE 'wait/io/file/innodb/%' WHERE p.SQL_TEXT LIKE 'ALTER%' OR p.SQL_TEXT LIKE 'CREATE%' OR p.SQL_TEXT LIKE 'DROP%' AND t.PROCESSLIST_STATE = 'Executing';
- 注意:
file_summary_by_event_name统计的是累计值,需在DDL开始前清空(TRUNCATE TABLE performance_schema.file_summary_by_event_name)再对比
为什么SHOW ENGINE INNODB STATUS不够用
该命令能显示锁等待和事务状态,但对IO压力无直接反映。它不会告诉你“当前这个ALTER TABLE正在往磁盘写入多少字节”,也不会区分是日志刷盘还是数据文件拷贝。更关键的是,它只返回最近一次的快照,而DDL的IO高峰可能转瞬即逝——比如COPY算法在数据复制阶段爆发式写入,但INNODB STATUS可能只捕捉到末尾的renaming table瞬间。
-
SHOW ENGINE INNODB STATUS里FILE I/O段仅显示全局IO吞吐趋势,无SQL粒度关联 - 它不记录
tmp_table创建过程中的临时文件IO(这些走的是server层文件API,归在wait/io/file/myisam/或wait/io/file/sql/下) - 若DDL使用
ALGORITHM=INSTANT,则几乎零IO,但INNODB STATUS也看不出这点——它根本不参与元数据变更
监控DDL IO时最容易忽略的点
很多人只盯着mysqld进程本身,却漏掉两个隐蔽但致命的干扰源:
- 从库上执行DDL会同时触发主库binlog拉取+本地回放,
slave_parallel_workers并发写入导致IO叠加;此时SHOW SLAVE STATUS的Seconds_Behind_Master可能仍为0,但iostat已爆表 -
innodb_log_file_size过小会导致DDL期间频繁checkpoint,引发额外日志刷盘IO;这在INPLACE重建索引时尤为明显,但错误日志里通常只报Log sequence number check point,不提IO - 第三方工具如
gh-ost虽规避了MDL锁,但其内部的chunk copy仍走INSERT ... SELECT,这部分IO会计入events_statements_history_long而非DDL语句本身——得查events_waits_history_long中wait/io/file/事件才抓得到
performance_schema里那些带时间戳的累加计数器,以及它们在DDL生命周期内的变化斜率。











