是,mysql 5.6+ 的 alter table ... alter column ... set default 是元数据操作,仅需短暂mdl写锁,不重写表、不重建索引、不锁表;但若误用 modify/change column 则触发全表拷贝。

ALTER TABLE ... ALTER COLUMN ... SET DEFAULT 会锁表吗?
MySQL 5.6+ 的 ALTER TABLE ... ALTER COLUMN ... SET DEFAULT 是**元数据操作**,不重写表、不重建索引,也不锁表(仅需短暂的 MDL 写锁)。但注意:该语法仅适用于修改默认值本身,不改动字段类型或长度。如果误写成 MODIFY COLUMN 或 CHANGE COLUMN,哪怕只改默认值,也会触发全表拷贝——这是最常踩的坑。
- ✅ 正确(轻量):
ALTER TABLE users ALTER COLUMN status SET DEFAULT 'active'; - ❌ 错误(重写表):
ALTER TABLE users MODIFY COLUMN status VARCHAR(20) DEFAULT 'active'; - ⚠️ 特别注意:MySQL 8.0.13+ 才支持对
JSON、GEOMETRY等类型字段用ALTER COLUMN ... SET DEFAULT;低版本会报错ERROR 1064
为什么 SET DEFAULT 不影响现有行数据?
设置默认值只是更新 INFORMATION_SCHEMA.COLUMNS 中的 COLUMN_DEFAULT 字段,不会触发行级更新。新插入的行才真正使用该默认值;已有数据完全不变。这点常被误解为“批量更新”,结果在大表上误执行 UPDATE 导致 IO 爆增。
- 现有行不受影响 → 零磁盘写入,IO 压力为 0
- 后续
INSERT INTO users (name) VALUES ('alice');才会自动填充'active' - 若想补全历史空值,必须显式
UPDATE users SET status = 'active' WHERE status IS NULL;—— 这才是真正的高 IO 操作
如何避免 ALTER COLUMN SET DEFAULT 在从库延迟加剧?
虽然主库执行快,但 DDL 语句在基于语句复制(SBR)模式下会完整重放;若从库负载高或磁盘慢,MDL 锁等待可能拖长复制延迟。推荐切换为基于行的复制(RBR),并确认 binlog_row_image = FULL(MySQL 5.7+ 默认满足)。
- 检查当前模式:
SELECT @@binlog_format;→ 应为'ROW' - 避免在业务高峰执行,哪怕它很快;DDL 仍会阻塞同表的其他 DDL 和部分 DML(如
CREATE INDEX) - 若用 pt-online-schema-change 工具,它不支持纯
SET DEFAULT场景(因为没必要),强行套用反而引入额外开销
MySQL 8.0+ 的 INSTANT 算法能加速 SET DEFAULT 吗?
不能。INSTANT 只适用于添加/删除列、重命名列等真正“不触碰数据页”的操作。ALTER COLUMN ... SET DEFAULT 本身就不涉及数据页,所以 INSTANT 对它无意义——它本来就是瞬间完成的。但如果你混用了其他变更(比如同时加列 + 改默认值),整个语句会退化为 COPY 或 INPLACE,失去瞬时性。
- ✅ 单独改默认值:
ALGORITHM=INSTANT可省略,效果一样 - ❌ 多操作混合:
ALTER TABLE t ALTER COLUMN c SET DEFAULT 1, ADD COLUMN x INT;→ 实际走 INPLACE,需评估锁时长 - 验证是否真 INSTANT:
SHOW PROCESSLIST;中看State是否为'altering table'(非 INSTANT)还是直接完成











