能,但仅限于严格满足六项条件:InnoDB引擎、末尾添加、字面量/NULL默认值、Dynamic行格式、无全文索引、单DDL操作;缺一则退化为INPLACE或COPY。

INSTANT算法在MySQL 8.0中真的能秒加列吗?
能,但仅限于特定条件。MySQL 8.0.12+ 引入的 INSTANT 算法确实可让某些 ALTER TABLE ... ADD COLUMN 操作不触发表拷贝、不锁表(只加元数据锁),耗时稳定在毫秒级——前提是新增列必须满足:不指定 BEFORE/AFTER 位置、不设默认值(或默认值为 NULL)、不加 PRIMARY KEY/UNIQUE 约束、且表未使用 COMPRESSED 行格式。
哪些ADD COLUMN操作会自动走INSTANT?
MySQL 会自动选择 INSTANT(无需显式写 ALGORITHM=INSTANT),只要满足全部以下条件:
- 新增列为末尾列(即不带
AFTER col_name或BEFORE col_name) - 列定义中不包含
DEFAULT子句,或仅含DEFAULT NULL - 列类型不是
JSON、GEOMETRY、全文索引列,也不涉及生成列(GENERATED) - 表引擎为
InnoDB,且ROW_FORMAT是DYNAMIC或COMPACT(非COMPRESSED) - 表没有启用
innodb_file_per_table=OFF(即必须独立表空间)
例如:ALTER TABLE users ADD COLUMN status TINYINT; 在符合条件的表上会自动 INSTANT;而 ALTER TABLE users ADD COLUMN created_at DATETIME DEFAULT NOW() AFTER name; 则一定 fallback 到 COPY。
如何确认某次ADD COLUMN是否真走了INSTANT?
执行后立刻查 INFORMATION_SCHEMA.INNODB_TABLES 或用 SHOW PROFILE 不够直观,最可靠方式是开启 innodb_monitor_output 或直接观察 ALTER 执行耗时 + 表锁等待:
- 执行前开监控:
SET GLOBAL innodb_monitor_enable = 'log'; - 执行
ALTER TABLE ... ADD COLUMN ...; - 查
SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME = 'ddl_log_inserts';—— 若该值增长,说明用了 INSTANT(它依赖 DDL 日志机制) - 更简单:对百万行表执行,若耗时 SHOW PROCESSLIST 中无
Waiting for table metadata lock长期阻塞,基本可判定成功
注意:即使满足全部条件,如果表刚经历过 OPTIMIZE TABLE 或早期版本升级遗留,也可能因内部元数据不一致导致降级到 INPLACE。
INSTANT加列后读写行为有哪些隐含限制?
INSTANT 列在物理存储上并不立即写入每行数据,而是靠运行时“补默认值”,这带来几个实际影响:
- 新增列首次被 SELECT 访问时,若该行此前未更新过,MySQL 会动态返回
NULL(哪怕你后来改了DEFAULT) -
UPDATE ... SET new_col = 1只改该行,不会批量回填旧数据;旧行仍保持“缺失”状态,直到被显式更新 - 使用
mysqldump导出时,INSTANT 列会被当作普通列处理,但恢复到低版本 MySQL(Unknown column 'xxx' in 'field list' - 备份工具如 Percona XtraBackup 8.0+ 支持 INSTANT 元数据,但老版本不识别,恢复可能丢列
真正需要全量填充默认值时,仍得走一次轻量 UPDATE 或后续 ALTER TABLE ... ALGORITHM=INPLACE 触发重写——INSTANT 解决的是“加列快”,不是“数据就位快”。


















