秒级修改列字符集

在MySQL中,当用户指定列的字符集为UTF-8时,会默认使用utf8mb3字符集,该字符集最大使用3个字节来存储字符。如果用户需要存储表情(emoji)等信息时,则需要将列字符集修改为utf8mb4。一般情况下,修改列字符集需要重建表,耗时较长,且对业务影响较大。PolarDB MySQL版支持秒级修改列字符集,使用该功能您可以快速地修改字符集,且对业务无感。

前提条件

集群版本需为以下版本之一:

  • PolarDB MySQL版8.0.1版本且修订版本为8.0.1.1.40及以上,您可以通过查询版本号来确认集群版本。

    说明

    您需要先配置loose_innodb_support_instant_modify_charset参数才能在PolarDB MySQL版8.0.1版本的集群上使用该功能。

  • PolarDB MySQL版8.0.2版本。

    说明

    PolarDB MySQL版8.0.2版本的集群默认支持秒级修改列字符集功能,无需配置任何参数。

使用限制

  • 仅支持修改列类型为CHAR、VARCHAR、ENUM以及TEXT的列的字符集。

  • 仅支持将列字符集由utf8mb3修改为utf8mb4,或将任意字符集修改为BINARY类型。

  • 需要修改列字符集的列上没有创建任何索引。

  • 修改列字符集前后,列的长度必须满足以下要求:

    • 修改列字符集前后,列的最大存储长度均小于256个字节,或均大于255个字节。存储长度为字符集实际消耗的存储长度。

      例如,某列使用的字符集为utf8mb3,且列类型为VARCHAR(85),由于utf8mb3最大使用3个字节来存储字符,因此,该列的最大存储长度为85*3=255字节。若将该列的字符集修改为utf8mb4,其最大存储长度为85*4=340字节,由于修改列字符集后的最大存储长度大于256个字节,因此,修改该列字符集时不能秒级完成。

    • 目标字符集的列的最大存储长度不能小于原字符集的列的最大存储长度。

      例如,某列类型为CHAR(120),且使用的字符集为utf8mb3,列的最大存储长度为120*3=360字节。修改为BINARY类型后,列的最大存储长度为120*1=120字节。因此,该列不满足秒级修改列字符集的要求。

使用方法

  1. 配置参数

    针对PolarDB MySQL版8.0.1版本,您需要将参数loose_innodb_support_instant_modify_charset的值设置为ON,才能使用秒级修改列字符集功能。设置参数值的具体操作请参见设置集群参数和节点参数

    参数名称

    参数级别

    说明

    loose_innodb_support_instant_modify_charset

    Global

    秒级修改列字符集功能控制开关。取值范围如下:

    • OFF(默认):关闭秒级修改列字符集功能。

    • ON:开启秒级修改列字符集功能。

  2. 修改列字符集

    • 指定ALGORITHM=INPLACE以强制使用秒级修改列字符集功能。示例如下:

      ALTER TABLE tablename MODIFY COLUMN test_column varchar(60) CHARACTER SET utf8mb4, ALGORITHM = INPLACE;

      使用上述语句时。若返回以下错误,表示当前修改列字符集操作不能以INPLACE算法执行,建议您查看参数loose_innodb_support_instant_modify_charset的值是否设置为ON,并仔细检查是否满足使用限制章节描述的情形。

      ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
    • 不指定ALGORITHM或指定ALGORITHM=DEFAULTPolarDB会自行选择执行速度最快的算法来执行修改操作。示例如下:

      ALTER TABLE tablename MODIFY COLUMN test_column varchar(60) CHARACTER SET utf8mb4, ALGORITHM = DEFAULT;
      ALTER TABLE tablename MODIFY COLUMN test_column varchar(60) CHARACTER SET utf8mb4;

使用效果

以包含一千万数据的表t1t2为例,测试开启和关闭秒级修改列字符集时,将列的字符集由utf8mb3修改为utf8mb4的执行效果。其中,表t1t2的表结构以及数据量完全相同。

  • 关闭秒级修改列字符集功能时,修改列的字符集需要重建表,执行时间大约需要1分钟左右,且整个DDL过程中只能执行查询操作。

    ALTER TABLE t1 MODIFY COLUMN c varchar(2)  CHARACTER SET utf8mb4 NOT NULL DEFAULT '';

    执行结果如下:

    Query OK, 10000000 rows affected (59.66 sec)
    Records: 10000000  Duplicates: 0  Warnings: 0
  • 开启秒级修改列字符集功能之后,修改列字符集可以无视表数据量大小,秒级完成修改列字符集操作。

    ALTER TABLE t2 MODIFY COLUMN c varchar(2)  CHARACTER SET utf8mb4 NOT NULL DEFAULT '',ALGORITHM = INPLACE;

    执行结果如下:

    Query OK, 0 rows affected (0.03 sec)
    Records: 0  Duplicates: 0  Warnings: 0

联系我们

若您对DDL操作有任何疑问,可通过钉钉搜索群号入群咨询。您可以直接@群内专家,并附上您要咨询的问题;同时群内也有PolarDB MySQL版小助手24*7小时在线回答您的问题。钉钉群号:15375044501。