RDS MySQL的秒级加列功能通过变更元数据实现快速加列操作,避免全表数据重建,可在秒级内完成,且与表数据量大小无关。秒级加列几乎不消耗额外系统资源,也不会对业务造成锁表或阻塞的影响,适用于需要频繁扩展表结构且对业务连续性要求较高的场景。
功能说明
RDS MySQL的秒级加列(Instant Add Column)通过变更数据字典的元数据来优化ADD COLUMN 操作。该功能避免了传统DDL操作对全表数据的修改或重建,实现加列操作在秒级内完成,且不受表数据量影响。
秒级加列与传统加列的核心优势对比:
| 对比项 | 传统加列(Copy或Inplace模式) | RDS秒级加列(Instant模式) | 
| 加列耗时 | 需要全表数据重建,耗时与表大小成正比。 | 仅修改元数据,操作时长可控制在秒级。 | 
| 资源消耗 | 临时占用大量系统资源(如IO、内存)。 | 几乎不消耗额外资源。 | 
| 业务影响 | 长事务或高并发场景可能阻塞在线业务。 | 无锁表或阻塞影响。 | 
| 表大小限制 | 无法支持大表快速加列。 | 支持任意大小表快速加列。 | 
前提条件
实例版本要求如下,当小版本不符合要求时,可以升级内核小版本:
- MySQL 8.0:所有内核小版本均支持。 
- MySQL 5.7:内核小版本大于等于20250331。 
使用限制
- 引擎限制:仅支持InnoDB引擎。 
- 表类型限制:不支持压缩表、带全文索引的表和临时表。 
- 操作限制:不支持多操作合并,例如在添加列的同时添加索引。 
- 默认加列位置: - MySQL版本 - 内核小版本 - 加列位置 - 5.7 - 大于等于20250331 - 默认最后一列。 - 8.0 - 低于20230630 - 默认最后一列。 - 大于等于20230630 - 支持在新增列时指定列位置。 
开启秒级加列
MySQL 8.0默认开启秒级加列,您无需修改参数即可使用该功能。MySQL 5.7需参考以下步骤开启秒级加列:
- 访问RDS实例列表,选择地域并单击目标实例ID。 
- 在左侧导航栏,单击参数设置。 
- 在可修改参数页签中搜索 - loose_innodb_instant_ddl_enabled参数,并在该参数的运行参数值列,修改参数值为ON。说明- 修改 - loose_innodb_instant_ddl_enabled参数可以立即生效且无需重启实例。
- 单击提交参数,在弹出的对话框中,选择生效的时间段,完成后单击确定。 
相关操作
使用秒级加列
- 指定 - ALGORITHM=INSTANT强制使用秒级加列:- ALTER TABLE <table_name> ADD COLUMN <column_name> <data_type> <constraints>, ALGORITHM = INSTANT;
- 不指定 - ALGORITHM,RDS MySQL运行时根据条件选择最优模式:- ALTER TABLE <table_name> ADD COLUMN <column_name> <data_type> <constraints>;
查看已执行秒级加列的表
- MySQL 5.7: - SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE INSTANT_COLS > 0;
- MySQL 8.0: - -- 内核小版本低于20230630 SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE INSTANT_COLS > 0; -- 内核小版本大于等于20230630 SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE TOTAL_ROW_VERSIONS > 0;
查看通过秒级加列添加的列
- MySQL 5.7: - 5.7版本在 - INFORMATION_SCHEMA库中新增了- INNODB_SYS_INSTANT_COLUMNS表,通过如下SQL查看秒级加列功能添加的列信息。- SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INSTANT_COLUMNS WHERE TABLE_ID = (SELECT TABLE_ID FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME = "<database_name>/<table_name>");
- MySQL 8.0: - 通过如下SQL查看表的列信息,若查询结果中 - HAS_DEFAULT列为1,则说明该列是通过秒级加列功能添加的。- SELECT * FROM INFORMATION_SCHEMA.INNODB_COLUMNS WHERE TABLE_ID = (SELECT TABLE_ID FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME = "<database_name>/<table_name>");