INSTANT加列仅对满足全部硬性条件的极简末尾加列生效:必须InnoDB引擎、无FULLTEXT索引、非压缩行格式、单操作语句、显式主键,且仅支持ADD COLUMN c INT NULL或DEFAULT常量,不支持函数默认值、NOT NULL隐式默认、AFTER/FIRST定位。

能秒加,但必须满足全部硬性条件;漏一条就 fallback 到几小时的 COPY 或直接报错 ERROR 1845。
哪些 ADD COLUMN 操作真正走 INSTANT?
INSTANT 只对极简的末尾加列生效,且默认值必须是常量或显式 DEFAULT NULL。它不是“MySQL 8.0 自动优化”,而是“全条件命中才启用”的窄通道:
-
ADD COLUMN c1 INT NULL✅(推荐:最稳妥) -
ADD COLUMN c2 VARCHAR(10) DEFAULT 'x'✅(非 NULL 常量默认值可支持) -
ADD COLUMN c3 DATETIME DEFAULT NOW()❌(函数默认值强制退化) -
ADD COLUMN c4 INT NOT NULL❌(没写 DEFAULT,隐含 DEFAULT 0,但 NOT NULL + 无显式 DEFAULT 会触发语义冲突) -
ADD COLUMN c5 INT AFTER id❌(8.0.28 及之前不支持位置指定;8.0.29+ 支持但需额外验证)
为什么 ALGORITHM=INSTANT 会突然报错 ERROR 1845?
这不是版本问题,而是五条硬门槛中至少一条未过。常见真实失效点:
- 表引擎不是
InnoDB(MyISAM、Memory直接不认) - 行格式为
COMPRESSED或KEY_BLOCK_SIZE > 0(查SELECT ROW_FORMAT, KEY_BLOCK_SIZE FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME = 'db/t1') - 表上存在
FULLTEXT索引(哪怕只有一条,INSTANT 就禁用) - 语句混了其他 DDL,例如
ADD COLUMN x INT, ADD INDEX idx_x (x)(逗号分隔也不行) - MySQL 8.0.12–8.0.27 中,表无显式主键且无
NOT NULL UNIQUE列(即依赖隐式主键)
如何验证 INSTANT 是否真正生效?
别只看执行时间短——小表本身快,容易误判。关键看是否与数据量脱钩:
- 对千万行或 TB 级表执行
ALTER TABLE t ADD COLUMN x INT NULL, ALGORITHM=INSTANT,耗时应稳定在0.01–0.05 秒,且SHOW PROCESSLIST中状态不出现altering table - 查系统表确认:
SELECT instant_cols FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME = 'db/t1'—— 值应为正整数(每成功一次 INSTANT 操作 +1),上限 64 - 观察磁盘 I/O:INSTANT 不产生任何用户数据页写入,
iostat -x 1中对应磁盘的%util和wr_sec/s应无明显波动
实操建议:安全第一,显式指定比默认 fallback 更可靠
永远显式写 ALGORITHM=INSTANT,而不是依赖 MySQL 自动选择:
- 成功:立刻完成,毫秒级
- 失败:立刻报
ERROR 1845 (0A000),你知道哪里不合规,可以立刻修正 - 不写:MySQL 静默降级到
INPLACE或COPY,你可能在凌晨三点才发现大表卡在copy to tmp table
INSTANT 的本质是“只改三处元数据”,老数据行物理上仍无该字段——这是性能来源,也是语义边界。一旦涉及行格式变更、索引重建、或需要旧数据“真实拥有”该列值,INSTANT 就不再适用。


















