MySQL 8.0.16+ 可通过 performance_schema.events_stages_current 估算部分 DDL 进度,但 SHOW PROCESSLIST 仅显示线程状态快照,无法反映真实执行阶段;需查 events_statements_current 的 STATE='EXECUTING' 确认是否真在执行,并优先排查 data_lock_waits、metadata_locks 和 INNODB_TRX 中的锁阻塞。

MySQL 原生不提供“剩余 X%”或“还剩 Y 分钟”的直接进度接口,但 8.0.16+ 可通过 performance_schema.events_stages_current 查到部分 DDL 的估算进度(仅限 ALGORITHM=INPLACE 且支持 stage 统计的操作)。
为什么 SHOW PROCESSLIST 看不到真实进度
SHOW PROCESSLIST 的 State 字段常显示 altering table 或 Waiting for table metadata lock,但这只是线程状态快照,不是执行阶段信号。它无法区分:是刚拿到锁还没干活、正在读主键、还是卡在 I/O 或锁等待上。更糟的是:INFO 列默认截断(最多 1024 字节),长 ALTER TABLE 语句直接变 NULL 或被砍掉。
- 常见错误现象:
State = altering table但Timer_wait几小时不动,实际已卡死 - 根本原因:DDL 内部被拆成多个子阶段,
PROCESSLIST只反映最外层线程状态 - 替代方案:必须查
performance_schema.events_statements_current拿完整语句和真实STATE(如EXECUTING)
怎么查当前 DDL 是否真在执行
先确认 performance_schema 已启用:SELECT @@performance_schema 返回 1 才有效。再运行:
SELECT THREAD_ID, SQL_TEXT, STATE, TIMER_WAIT FROM performance_schema.events_statements_current WHERE (SQL_TEXT LIKE 'ALTER%' OR SQL_TEXT LIKE 'CREATE%' OR SQL_TEXT LIKE 'DROP%') AND STATE = 'EXECUTING';
STATE = 'EXECUTING' 才代表真正干活;QUEUED 或 CALCULATING 都不算。如果查不到结果,说明 DDL 还没进入执行阶段——大概率卡在元数据锁上,需立刻查 performance_schema.metadata_locks 和 data_lock_waits。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
怎么估算进度百分比(仅限部分 DDL)
这个能力只对 ALGORITHM=INPLACE 且属于 InnoDB 内置支持的操作有效(如加索引、加列),ALGORITHM=COPY 或涉及外键重建时,WORK_COMPLETED/WORK_ESTIMATED 常为 NULL。
- 先启用 stage 监控:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'events_stages%'; - 再查当前阶段:
SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_current WHERE EVENT_NAME LIKE 'stage/innodb/%' AND WORK_ESTIMATED > 0; - 典型可估算阶段:
stage/innodb/alter table (read PK and internal sort)、stage/innodb/alter table (write clustered index) - 进度计算:
ROUND(100 * WORK_COMPLETED / WORK_ESTIMATED, 2)—— 注意分母为 0 会报错,要加判断
容易被忽略的卡点排查顺序
DDL 表面不动,90% 是卡在锁或资源上,而不是“慢”。别盯着 events_stages_current 死看,优先扫这三张表:
-
performance_schema.data_lock_waits:有记录?说明正等行锁或间隙锁 -
performance_schema.metadata_locks:找OBJECT_TYPE = 'TABLE'且LOCK_TYPE = 'EXCLUSIVE'的持有者 -
information_schema.INNODB_TRX:看有没有长事务(TRX_STARTED时间很早),它会阻塞 DDL 获取元数据锁
真正难搞的不是进度计算,而是区分“真慢”和“假卡”——前者调优 I/O 或降并发,后者杀掉阻塞事务就秒恢复。

















