ddl卡住会导致所有dml排队等待mdl锁,引发连接池打满、接口超时、业务雪崩;千万级表加字段可能锁表数十秒至数分钟,主从延迟还会导致字段缺失、类型错误等隐蔽故障。

DDL在高峰期会直接卡死业务请求
MySQL执行ALTER TABLE这类DDL时,多数操作需获取表级MDL写锁,而此时所有对该表的DML(SELECT、INSERT、UPDATE、DELETE)都依赖MDL读锁——读锁与写锁互斥。结果就是:只要DDL没拿到锁,后续所有业务语句全排队等待;一旦排队积压,连接池迅速打满,应用层开始超时、重试、雪崩。
常见错误现象包括:
• 接口响应从100ms飙升至30s+
• MySQL Threads_running 持续高于50甚至破百
• 监控里出现大量Waiting for table metadata lock状态
- 哪怕只是加个字段(
ADD COLUMN),在千万级表上也可能锁表几十秒到数分钟 -
MODIFY COLUMN或DROP COLUMN在MySQL 5.7中默认走COPY模式,全程锁表+全量拷贝,风险极高 - MySQL 8.0虽支持部分
INSTANTDDL(如加列),但仅限于末尾新增、不涉及数据重排的场景,不能盲目信任
主从延迟会放大故障影响范围
主库执行DDL是原子动作,几乎瞬间完成;但从库SQL线程单线程回放,尤其遇到大表ALTER,可能卡住数小时。这意味着:读写分离架构下,从库查询返回的是DDL前的旧结构,字段缺失、类型不匹配、索引不可用——业务报错不是“连不上数据库”,而是“查不到字段”“类型转换失败”这类更隐蔽的问题。
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
- ETL任务可能因字段变更中断,BI报表数据断更
- 微服务若缓存了表结构(如MyBatis的
ResultMap),重启前一直报Unknown column - 延迟期间无法做主从切换,故障恢复窗口被彻底锁死
磁盘和IO压力可能触发连锁崩溃
COPY模式DDL(如VARCHAR改TEXT、添加全文索引)会生成临时表,占用等量磁盘空间;同时全表扫描+写入带来持续IO峰值。生产环境磁盘往往已接近80%水位,一次DDL就可能触发ERROR 3(磁盘满)、innodb_force_recovery启用,甚至实例自动宕机。
- 执行前不检查
df -h /var/lib/mysql和SHOW TABLE STATUS预估空间,等于埋雷 - 未监控
Innodb_data_pending_fsyncs和io_wait指标,容易错过IO瓶颈预警 - 某些云厂商RDS对临时表空间有硬限制,超限直接中止DDL且不回滚原表
回滚成本远高于预期
DDL失败后,MySQL不会自动回滚已写入的数据(比如只拷贝了80%的行),而是留下损坏的临时表或半成品元数据。人工介入时,你面对的不是“删掉新建的列”,而是:如何安全清理残留文件、修复数据字典、同步主从binlog位置——这些操作本身又需要锁表。
-
DROP COLUMN或MODIFY COLUMN导致数据截断(如DECIMAL(10,2)→INT),数据永久丢失,备份是唯一救命稻草 - 线上误执行
TRUNCATE TABLE,即使有备份,恢复也要停服+导入,RTO通常以小时计 - 没有提前生成反向SQL(如把
ADD COLUMN转为DROP COLUMN),故障时只能靠DBA手写,极易出错










