instant算法自mysql 8.0.12起支持末尾加列,8.0.29起支持任意位置增删列及多列操作;需innodb表、非compressed格式、无全文/空间索引、字段非主键/自增/存储生成列、默认值为字面量或null;显式指定algorithm=instant可避免静默降级,行版本上限64,超限需重建表重置。

能秒加,但不是所有情况都行;不显式写 ALGORITHM=INSTANT 也大概率会走它,但出问题时你根本不知道是它在“背锅”。
INSTANT 算法到底在什么版本、什么条件下可用?
MySQL 8.0.12 起支持 ADD COLUMN 的 INSTANT,但仅限末尾加列;8.0.29 起才真正放开:支持 AFTER/FIRST 定位加列、支持 DROP COLUMN、支持单语句多列增删。别信“8.0 就行”——先查版本:SELECT VERSION();。低于 8.0.12 的,INSTANT 直接报错 ERROR 1845 (0A000);8.0.12–8.0.28 之间,AFTER col_name 会自动 fallback 到 INPLACE,耗时可能几分钟到几小时。
- 必须是 InnoDB 表,且
ROW_FORMAT != COMPRESSED(压缩表不支持) - 不能有全文索引(
FTS)或空间索引 - 新增字段不能是主键、自增列、生成列(virtual/generated column 可以,但 stored 不行)
- 默认值不能是子查询或函数(如
NOW()、UUID()),只接受字面量或NULL
为什么显式写 ALGORITHM=INSTANT 是刚需?
虽然 MySQL 默认会“优先尝试” INSTANT,但一旦不满足条件,它会静默降级为 INPLACE 或 COPY,并继续执行——你看到的是“成功”,实际却是锁表几分钟。显式指定后,不满足就直接报错,不让你蒙在鼓里。错误信息也更明确,比如:
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE.
这时你就能立刻判断:是不是加在中间了?是不是表用了压缩?是不是有全文索引?而不是等业务报警才发现 ALTER 卡了 7 分钟。
- 加列到末尾:
ALTER TABLE orders ADD COLUMN is_archived TINYINT DEFAULT 0, ALGORITHM=INSTANT; - 加列到指定位置(8.0.29+):
ALTER TABLE orders ADD COLUMN priority INT AFTER user_id, ALGORITHM=INSTANT; - 一次加多列:
ALTER TABLE orders ADD COLUMN a INT, ADD COLUMN b VARCHAR(32), ALGORITHM=INSTANT;
行版本数(TOTAL_ROW_VERSIONS)超限怎么办?
每次 ADD 或 DROP COLUMN 都会增加一个行版本,上限是 64(MySQL 9.1 才升到 255)。超过后报错:
ERROR 4092 (HY000): Maximum row versions reached for table test/orders. No more columns can be added or dropped instantly.
这不是临时故障,是硬限制。查当前版本数:SELECT TOTAL_ROW_VERSIONS FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME = 'test/orders';。一旦接近 60,就得警惕——别再零散加字段,该合并 DDL 就合并,该重建表就重建。用 ALGORITHM=COPY 或 ALGORITHM=INPLACE 重建一次,版本计数归零。
- 重建表本身不触发新版本(因为是全新结构),但代价是 I/O 和锁
- 不要依赖“只读期间多加几次”,64 是全局累计值,不是会话级
- 监控脚本里建议把
TOTAL_ROW_VERSIONS加入巡检项
INSTANT 字段读写行为和默认值怎么生效?
INSTANT 加的字段对老数据“按需填充”:SELECT 时才根据元数据里的默认值补上,物理行数据没动过。所以老行查出来是 DEFAULT 值,新行插入时才真实写入该字段值。这点影响不大,但要注意两个边界:
- 如果字段定义为
NOT NULL且无默认值,INSTANT 会拒绝(ERROR 1138),因为老数据无法满足约束 - 如果后续用
UPDATE显式给某老行设值,那行会被重写为新版本格式,头部标记更新,但不会批量转换全表 - 备份工具如 XtraBackup 8.0.29+ 才完整兼容 INSTANT 行版本,旧版可能漏掉版本元数据
最易被忽略的其实是“降级不可逆”——一旦因版本超限或条件不满足被迫用 INPLACE/COPY 执行过一次 ADD COLUMN,之后再想切回 INSTANT,得先确保表结构干净(无冗余列、无压缩、无 FTS),否则 INSTANT 还是走不通。











