他的回复:
Online DDL 的核心是「把阻塞性的表重建动作,改成在后台增量进行 + 用 row log 补齐增量」,从 5.6 起引入,8.0 又加了 instant 算法。三种算法:ALGORITHM=INSTANT(8.0+):只改数据字典元数据,秒级完成,不重建表。适用:加列(默认加到末尾)、改列默认值、改 ENUM/SET 末尾追加值、重命名表。ALGORITHM=INPLACE:不建临时表,在原地重建/修改,期间允许并发 DML(靠 row log 记录在 DDL 期间产生的变更,最后回放)。适用:加/删二级索引、改列长度(不缩小)、OPTIMIZE TABLE、加主键(需重建)。ALGORITHM=COPY:拷表 + 全程锁,最慢,基本等于 offline。锁的三种粒度(用 LOCK=NONE / SHARED / EXCLUSIVE 指定,MySQL 会自动降级取最强可用的):LOCK=NONE:不阻塞读写,真正的「Online」;LOCK=SHARED:允许读、阻塞写;LOCK=EXCLUSIVE:读写全阻塞。哪些常见 ALTER 可以做到不锁表(LOCK=NONE):创建/删除二级索引(CREATE INDEX、DROP INDEX);8.0 加列(INSTANT,秒级);修改列默认值、改列名(8.0)、改 VARCHAR 长度(字节数不减小且不超过 255→256 这类跨长度字节边界的情况);增删外键(需各自开关 foreign_key_checks);OPTIMIZE TABLE、ALTER TABLE ... FORCE(INPLACE + 并发 DML)。哪些一定会锁(要避开业务高峰):删列、改列类型(如 INT→BIGINT)、改字符集、缩 VARCHAR 长度、加主键(要重建数据)、改表级 ROW_FORMAT。实操建议:先显式写 ALTER TABLE t ADD COLUMN c INT, ALGORITHM=INSTANT, LOCK=NONE; —— 不支持时 MySQL 会直接报错,而不是悄悄退化成 COPY,避免踩坑;大表改结构优先用 gh-ost / pt-online-schema-change(触发器或 binlog 追增量),可控可限速可暂停;注意 元数据锁(MDL):即使 DDL 本身是 LOCK=NONE,若事务里有未提交的旧事务持有 MDL,DDL 会卡在 Waiting for table metadata lock 并阻塞后续所有查询——上线前先查 performance_schema.metadata_locks 杀掉长事务;从库延迟:DDL 在主库完成后才传到从库,大表 DDL 会造成从库延迟突增,读写分离场景要评估。