秒级修改列类型

AliSQL支持秒级修改列类型功能,修改列类型时仅修改元数据而无需全量拷贝数据,可大幅降低修改耗时,提升运维效率。

功能说明

背景:社区MySQL8.0版本开始支持INSTANT DDL,加列和删列操作只需要修改元数据,而无需拷贝数据,DDL可以秒级完成。但是对于修改列类型的操作,社区MySQL 8.0还是只能通过COPY DDL的方式执行,DDL耗时较长。AliSQL在社区MySQL的基础上,支持秒级修改列类型功能,通过INSTANT DDL的方式执行修改列类型操作。

简介:AliSQL 秒级修改列类型(Instant Modify Column)功能在修改列类型时无需再进行数据拷贝,而是复用社区INSTANT DDL的执行框架,在修改列类型时,只需要进行元数据的修改,整个修改列类型的执行过程和其他INSTANT DDL完全相同,修改列类型的过程可以秒级完成。

适用范围

  • 如需使用秒级修改列类型功能,数据库大版本须为MySQL 8.0且内核小版本大于等于20251031。当版本不符合要求时,可以升级数据库大版本内核小版本

  • 使用该功能时,有以下限制条件:

    • 引擎限制:仅支持InnoDB引擎。

    • 索引限制:不支持修改索引列。

    • 列类型限制:仅支持对以下数据类型进行类型修改或长度扩展:

      • 整数类型变大(类型修改):包括TINYINTSMALLINTMEDIUMINTINTBIGINT类型从小变大。例如:支持INTBIGINT修改,不支持BIGINTINT修改。

      • 字符串类型变长(长度扩展):包括CHAR类型和VARCHAR类型变长,例如:CHAR(M)修改至CHAR(N),需要N > M。

    • 其他限制:不支持修改分区键包含的列。

参数管理

参数说明

秒级修改列类型功能受以下参数控制:

参数名称

说明

loose_rds_upgrade_datatype_instant_enable

  • 描述:秒级修改列类型功能开关。

  • 参数范围:全局参数。

  • 数据类型:Boolean

  • 默认值:OFF

  • 取值范围:ONOFF

  • 是否需要重启实例:否。

loose_rds_upgrade_datatype_online_enable

  • 描述:在线修改列类型功能开关。

  • 参数范围:全局参数。

  • 数据类型:Boolean

  • 默认值:OFF

  • 取值范围:ONOFF

  • 是否需要重启实例:否。

loose_innodb_instant_ddl_enabled

  • 描述:INSTANT DDL总开关。

  • 参数范围:全局参数。

  • 数据类型:Boolean

  • 默认值:ON

  • 取值范围:ONOFF

  • 是否需要重启实例:否。

修改参数

  1. 访问RDS实例列表,在上方选择地域,然后单击目标实例ID。

  2. 在左侧导航栏中单击参数设置

  3. 可修改参数页签内搜索待修改参数,并配置参数值。

  4. 单击确定,然后单击提交参数,并在弹出的窗口中选择生效的时间段。

使用方法

您需要在控制台上将以下三个参数的值设置为ON,开启秒级修改列类型功能:

  • loose_rds_upgrade_datatype_online_enable

  • loose_rds_upgrade_datatype_instant_enable

  • loose_innodb_instant_ddl_enabled

为方便后续说明,假设待修改的数据表为t1,表结构如下所示:

CREATE TABLE `t1` (
  `id` int NOT NULL,
  `c1` char(10) DEFAULT NULL,
  `c2` varchar(10) DEFAULT NULL,
  `c3` char(100) DEFAULT NULL,
  `c4` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

指定INSTANT算法修改列类型

您可以指定INSTANT算法秒级修改列类型(含类型修改和长度扩展):

  • 类型修改:指定INSTANT算法修改c1列类型为bigint

  • 长度扩展:指定INSTANT算法扩展c2c3列类型长度。

说明

如果将算法指定为INPLACE,则表示在线修改列类型,而非秒级修改。

-- 类型修改:指定INSTANT算法修改c1列类型
ALTER TABLE `t1` MODIFY `c1` bigint DEFAULT NULL, ALGORITHM=INSTANT;

-- 查看修改结果
SHOW CREATE TABLE `t1`\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id` int NOT NULL,
  `c1` bigint DEFAULT NULL,
  `c2` char(10) DEFAULT NULL,
  `c3` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
1 row in set (0.00 sec)

-- 长度扩展:指定INSTANT算法扩展c2、c3列类型长度
ALTER TABLE `t1` MODIFY `c2` char(20) DEFAULT NULL, ALGORITHM=INSTANT;
ALTER TABLE `t1` MODIFY `c3` varchar(100) DEFAULT NULL, ALGORITHM=INSTANT;

-- 查看修改结果
SHOW CREATE TABLE `t1`\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id` int NOT NULL,
  `c1` bigint DEFAULT NULL,
  `c2` char(20) DEFAULT NULL,
  `c3` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
1 row in set (0.00 sec)

不指定算法修改列类型

不指定算法时,系统会自动选择最合适的算法执行列类型修改操作。

ALTER TABLE `t1` MODIFY `c1` bigint DEFAULT NULL;

查看秒级修改的列

秒级修改的列可以在INFORMATION_SCHEMA.INNODB_COLUMNS表中的PARENT_PHYSICAL_POSITION字段查看:如果该字段值为-1则表示该列为正常列,其他情况为秒级修改的列。

-- 通过 INNODB_TABLES 查询示例表的ID(TABLE_ID)
SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME = 'demo/t1';
+----------+---------+------+--------+-------+------------+---------------+------------+--------------+--------------------+-----------------------+-----------------------+---------------------+
| TABLE_ID | NAME    | FLAG | N_COLS | SPACE | ROW_FORMAT | ZIP_PAGE_SIZE | SPACE_TYPE | INSTANT_COLS | TOTAL_ROW_VERSIONS | INITIAL_COLUMN_COUNTS | CURRENT_COLUMN_COUNTS | TOTAL_COLUMN_COUNTS |
+----------+---------+------+--------+-------+------------+---------------+------------+--------------+--------------------+-----------------------+-----------------------+---------------------+
|     2197 | demo/t1 |   33 |      7 |  1129 | Dynamic    |             0 | Single     |            0 |                  3 |                     4 |                     4 |                   7 |
+----------+---------+------+--------+-------+------------+---------------+------------+--------------+--------------------+-----------------------+-----------------------+---------------------+
1 row in set (0.00 sec)

-- 通过TABLE_ID在 INNODB_COLUMNS 中检索列信息
-- 在查询结果的 PARENT_PHYSICAL_POSITION 字段可以找到秒级修改的列(值不为-1)
SELECT * FROM INFORMATION_SCHEMA.INNODB_COLUMNS WHERE TABLE_ID = 2197;
+----------+------+-----+-------+---------+-----+-------------+---------------+---------------+-----------------+--------------+------------------+--------------------------+
| TABLE_ID | NAME | POS | MTYPE | PRTYPE  | LEN | HAS_DEFAULT | DEFAULT_VALUE | VERSION_ADDED | VERSION_DROPPED | PHYSICAL_POS | VERSION_MODIFIED | PARENT_PHYSICAL_POSITION |
+----------+------+-----+-------+---------+-----+-------------+---------------+---------------+-----------------+--------------+------------------+--------------------------+
|     2197 | id   |   0 |     6 |    1283 |   4 |           0 | NULL          |             0 |               0 |            0 |                0 |                       -1 |
|     2197 | c1   |   1 |     6 |    1032 |   8 |           1 | NULL          |             1 |               0 |            6 |                0 |                        3 |
|     2197 | c2   |   2 |    13 | 2162942 |  60 |           1 | NULL          |             2 |               0 |            7 |                0 |                        4 |
|     2197 | c3   |   3 |    12 | 2166799 | 300 |           1 | NULL          |             3 |               0 |            8 |                0 |                        5 |
+----------+------+-----+-------+---------+-----+-------------+---------------+---------------+-----------------+--------------+------------------+--------------------------+
4 rows in set (0.02 sec)