秒级修改列字符集

AliSQL支持秒级修改列字符集功能,修改列字符集时仅修改元数据而无需重建表,可大幅降低字符集修改耗时,提升运维效率。

功能说明

背景:社区MySQLUTF-8字符集的默认实现是utf8mb3,由于utf8mb3字符集最大使用3个字节来存储1个字符,所以当用户需要存储表情(emoji)等4字节信息时,会出现信息丢失。社区从8.0版本开始将默认字符集修改为utf8mb4,但修改存量表中的列字符集时通常需要重建表,耗时较长。

简介:AliSQL支持秒级修改列字符集(Instant Modify Column Charset)功能。在修改列字符集时,无需通过“新建临时表+拷贝数据”的方式实现表重建,仅需要修改元数据,即可实现字符集秒级修改。

算法:在使用秒级修改列字符集功能时,MySQL 5.7版本仅支持INPLACE算法,8.0版本支持INPLACEINSTANT算法,两种算法在实际执行过程中均只修改元数据。

适用范围

如需使用秒级修改列字符集功能,实例的数据库版本需满足以下条件。当小版本不符合要求时,可以升级内核小版本

  • MySQL 8.0:内核小版本大于等于20230630。

  • MySQL 5.7:内核小版本大于等于20251031。

说明

MySQL 8.020251031之后支持INPLACEINSTANT算法,在20251031之前仅支持INPLACE算法。

使用秒级修改列字符集功能时,有以下限制:

  • 列类型限制:仅支持对CAHRVARCHAR类型的列字符集转换。

  • 字符集限制:仅支持utf8/utf8mb3转换为utf8mb4

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

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

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

  • 列长度限制:修改列字符集前后,列的最大存储长度均小于256字节,或均大于等于256字节。以utf8/utf8mb3转换为utf8mb4为例:

    • 对于utf8/utfbmb3字符集,1字符使用3字节存储,256字节的临界值为85字符。

    • 对于utf8mb4字符集,1字符使用4字节存储,256字节的临界值为63字符。

    image

    所以只有当列定义的长度(以字符为单位计算)在(0,63]或(85, 65535] 区间内时,才能支持秒级修改列字符集。

参数管理

参数说明

仅当MySQL8.0版本且需要指定INSTANT算法时,支持修改以下参数:

参数名称

说明

loose_rds_upgrade_datatype_instant_enable

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

  • 参数范围:全局参数。

  • 数据类型:Boolean

  • 默认值:OFF

  • 取值范围:ONOFF

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

loose_innodb_instant_ddl_enabled

  • 描述:Instant DDL 总开关。

  • 参数范围:全局参数。

  • 数据类型:Boolean

  • 默认值:ON

  • 取值范围:ONOFF

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

修改参数

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

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

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

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

使用方法

假设待修改的数据表为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;

指定算法修改列字符集

您可以在修改列字符集时指定INPLACEINSTANT算法。

指定INPLACE算法

-- 指定INPLACE算法修改c1、c2列的字符集为utf8mb4
ALTER TABLE `t1` MODIFY `c1` char(10) CHARACTER SET utf8mb4 DEFAULT NULL, ALGORITHM=INPLACE;
ALTER TABLE `t1` MODIFY `c2` varchar(10) CHARACTER SET utf8mb4 DEFAULT NULL, ALGORITHM=INPLACE;

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

指定INSTANT算法

-- 指定INSTANT算法修改c3、c4列的字符集为utf8mb4
ALTER TABLE `t1` MODIFY `c3` char(100) CHARACTER SET utf8mb4 DEFAULT NULL, ALGORITHM=INSTANT;
ALTER TABLE `t1` MODIFY `c4` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL, ALGORITHM=INSTANT;

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

不指定算法修改列字符集

修改列字符集时,如果不指定算法执行,MySQL会自动选择最合适的算法执行。

-- 不指定算法修改c1列的字符集为utf8mb4
ALTER TABLE `t1` MODIFY `c1` char(10) CHARACTER SET utf8mb4 DEFAULT NULL;