要查正在执行的完整DDL语句,须用performance_schema.events_statements_current并确保performance_schema=ON、STATE='EXECUTING'且SQL_TEXT以DDL关键词开头;查DDL是否被锁住需查metadata_locks表中LOCK_STATUS='PENDING'或LOCK_TYPE='EXCLUSIVE'的记录;确认DDL线程是否活跃需结合threads表的PROCESSLIST_STATE和INNODB_TRX中TRX_STATE='LOCK WAIT'的阻塞事务;events_stages_current仅对ALGORITHM=INPLACE的DDL有效且需提前启用stage消费者。

查正在执行的 DDL 语句:别信 SHOW PROCESSLIST 的截断信息
SHOW PROCESSLIST 显示的 Info 列默认最多 1024 字节,长 ALTER TABLE 会被砍掉,你看到的可能是 ALTER TABLE t ADD COLUMN ... 后面一堆省略号,根本不知道加的是什么字段、用的什么算法。
真正能拿到完整语句的,只有 performance_schema.events_statements_current:
- 必须确保
performance_schema = ON(查SELECT @@performance_schema返回 1) - 过滤条件要同时满足:
STATE = 'EXECUTING'(不是QUEUED或CALCULATING),且语句以ALTER、CREATE、DROP等 DDL 关键词开头 - 示例查询:
SELECT THREAD_ID, SQL_TEXT, TIMER_WAIT FROM performance_schema.events_statements_current WHERE STATE = 'EXECUTING' AND SQL_TEXT REGEXP '^(ALTER|CREATE|DROP|RENAME|TRUNCATE)';
查 DDL 是否被锁住:重点看 metadata_locks 表
DDL 卡在 altering table 状态不动?大概率是元数据锁(MDL)被别的会话占着。而阻塞者往往在 SHOW PROCESSLIST 里显示为 Sleep,Info 为空,完全看不出问题。
performance_schema.metadata_locks 是唯一能直接暴露“谁拿了锁、谁在等锁”的表:
-
LOCK_TYPE = 'EXCLUSIVE'→ 该线程持有排他 MDL(比如一个未提交事务里的SELECT ... FOR UPDATE) -
LOCK_STATUS = 'PENDING'→ 该线程正在等待获取 MDL(通常是那个卡住的ALTER) - 关键字段
OWNER_THREAD_ID可关联performance_schema.threads查到对应连接的PROCESSLIST_ID和用户信息
常用诊断语句:
SELECT OBJECT_SCHEMA, OBJECT_NAME, LOCK_TYPE, LOCK_STATUS, OWNER_THREAD_ID FROM performance_schema.metadata_locks WHERE LOCK_STATUS = 'PENDING' OR LOCK_TYPE = 'EXCLUSIVE';
确认 DDL 线程是否真活跃:结合 threads 和 INNODB_TRX
仅靠语句和锁还不够——得确认那个 DDL 线程本身还活着、没崩溃、也没被误杀。
performance_schema.threads 能告诉你线程当前状态:
-
PROCESSLIST_STATE是Executing还是Waiting on condition?后者常意味着卡在锁或 I/O -
PROCESSLIST_INFO为空不等于没执行;它只反映“当前正在跑的语句”,DDL 的子阶段(如索引构建)不会刷到这里
如果怀疑是 InnoDB 行级锁阻塞(比如 DDL 要重建二级索引,却被一个长事务锁住了某行),就得查 information_schema.INNODB_TRX:
- 找
TRX_STATE = 'LOCK WAIT'或TRX_STARTED时间异常早的事务 - 记下
TRX_MYSQL_THREAD_ID,再回threads表定位具体连接 - 注意:
INNODB_TRX不记录 DDL 自身事务(DDL 是非事务性操作),只记录“拦路”的普通事务
为什么 events_stages_current 有时查不到进度
想看 DDL 做到哪一步了?performance_schema.events_stages_current 确实能返回 stage/innodb/alter table (write clustered index) 这类阶段,但有严格前提:
- 必须是
ALGORITHM = INPLACE的 DDL(如加索引、加列),ALGORITHM = COPY或涉及外键重建时,WORK_COMPLETED/WORK_ESTIMATED常为NULL - 必须提前开启 stage 消费者:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'events_stages%'; - 即使满足条件,也只对部分内部阶段有效;像 “copy to tmp table” 或 “rename result table” 这些收尾阶段,可能根本不进
events_stages_current
所以别指望它总能给出进度条——它只是个有限线索,不是万能仪表盘。


















