应查询performance_schema.events_statements_current确认STATE='EXECUTING'且SQL_TEXT含ALTER/CREATE,再联查metadata_locks和INNODB_TRX定位锁阻塞,三表交叉验证才能准确判断DDL是否真实执行而非卡在元数据锁等待。

DDL执行中怎么查进度,而不是只看“Waiting for metadata lock”
MySQL原生不提供ALTER等DDL的百分比进度条,但可以通过组合performance_schema和sys视图间接判断是否在真实执行、卡在哪一阶段。关键不是找“进度数字”,而是确认语句是否已脱离排队、是否正在读写数据页或重写表。
-
performance_schema.events_statements_current里查到STATE = 'EXECUTING'且SQL_TEXT含ALTER/CREATE,说明DDL已进入实际执行阶段(不是锁等待) - 若
STATE是QUEUED或为空,大概率卡在元数据锁——立刻去查performance_schema.metadata_locks,看谁持有SCH_M锁 - 对
ALGORITHM=INPLACE的ALTER(如加列),执行中会反复触发table_io_waits_summary_by_table中的I/O统计上涨;而COPY算法则会在innodb_buffer_pool_pages_data持续增长
为什么sys.schema_table_statistics_with_buffer不能直接反映DDL进度
这个视图本质是聚合performance_schema.table_io_waits_summary_by_table和information_schema.INNODB_BUFFER_PAGE的快照,只统计“已完成”的I/O和缓存页访问,对正在执行的DDL无实时反馈。它更适合事后分析哪张表被频繁访问,而非监控当前DDL是否卡住。
- DDL执行时,
schema_table_statistics_with_buffer里的io_read_requests可能长时间不动——因为InnoDB在内部刷脏页或做排序,不走常规表I/O路径 - 该视图不包含
THREAD_ID或EVENT_ID关联字段,无法与events_statements_current中的具体DDL线程绑定 - 如果DDL用的是
ALGORITHM=COPY,新表名不会出现在该视图中(临时表名形如#sql-ib12345,且不计入schema统计)
真正能定位DDL卡点的三个核心表
单靠一个视图或命令基本无效,必须交叉验证这三个表:
-
performance_schema.events_statements_current:确认语句是否在EXECUTING,SQL是否完整(需提前设max_allowed_packet足够大) -
performance_schema.metadata_locks:查OBJECT_TYPE = 'TABLE'且LOCK_TYPE = 'EXCLUSIVE'的记录,看OWNER_THREAD_ID对应哪个线程,再反查threads表确认状态 -
information_schema.INNODB_TRX:虽然DDL本身不进此表,但如果看到长事务(TRX_STARTED时间远早于DDL发起时间),它很可能正持有行锁或间隙锁,阻塞DDL获取元数据锁
容易被忽略的配置前提
所有上述查询的前提是performance_schema必须启用且相关采集器打开,否则返回空结果不是没DDL,而是没开监控。
- 先执行
SELECT @@performance_schema;,返回1才有效;若为0,需重启mysqld并设performance_schema=ON -
events_statements_current默认只采集statement/sql类事件,要确保setup_instruments中statement/sql/alter*和statement/sql/create*为ENABLED='YES' -
metadata_locks表在MySQL 5.7.3+才稳定可用,5.6及更早版本只能靠SHOW PROCESSLIST+ 猜测


















