在MySQL生态中,修改字段的类型需要使用COPY算法对全表数据进行重建,且重建过程中目标表只能查询数据,不能并发的写入数据。更糟糕的是,COPY算法采用单线程进行全表重建,其效率较低。因此,修改字段类型操作一直是MySQL生态下的痛点问题。为了解决这一问题,PolarDB MySQL版支持秒级修改字段(Instant Modify Column)功能,在修改字段类型时,只需变更表定义信息,无需修改已有数据,可以快速完成对任意大小表的字段类型修改操作。本文介绍如何使用秒级修改字段类型功能。
前提条件
PolarDB MySQL版8.0.2版本且修订版本为8.0.2.2.28及以上,您可以通过查询版本号来确认集群版本。
参数说明
参数名 | 级别 | 说明 |
参数名 | 级别 | 说明 |
| Global | 秒级修改字段功能控制开关。取值范围如下:
|
| Global | 设置单表允许的秒级修改字段最大次数。 取值范围:1~64。 默认值为16。 |
PolarDB MySQL版秒级修改字段功能目前处于灰度发布阶段。如需使用请前往配额中心,根据配额ID
polarm_82_instant_modify_column
找到配额名称,在对应的操作列单击申请来开通该功能。
使用限制
仅允许对以下数据类型进行长度扩展变更,不支持秒级修改除长度外的其他字段属性。具体支持的变更类型如下:
整数类型:支持在
TINYINT
、SMALLINT
、MEDIUMINT
、INT
和BIGINT
类型之间秒级修改,但仅支持秒级扩大长度,不支持秒级缩小长度。例如,
INT
类型可以秒级修改为BIGINT
类型,但无法将BIGINT
类型秒级修改为INT
类型。字符串类型:
支持
VARCHAR(N)
类型秒级修改为VARCHAR(N+M)
类型,其中N和M均为大于0的正整数。例如,
VARCHAR(50)
类型可以秒级修改为VARCHAR(300)
类型,但不支持将VARCHAR(300)
类型秒级修改为VARCHAR(50)
类型。支持
CHAR(N)
类型秒级修改为CHAR(N+M)
类型,其中N和M均为大于0的正整数。例如,
CHAR(30)
类型可以秒级修改为CHAR(50)
类型,但不支持将CHAR(50)
类型秒级修改为CHAR(30)
类型。
仅支持行格式(Row Format)为
COMPACT
和DYNAMIC
的表。被修改的字段不能是索引字段。
不支持分区表进行秒级修改字段操作。
不支持使用全文索引或空间索引的表。
不支持在同一条SQL中同时执行除秒级修改字段以外的其他DDL操作。
您可以在执行DDL操作前使用EXPLAIN DDL功能,直观地判断当前DDL操作是否支持INSTANT操作。详细内容请参见EXPLAIN DDL。
使用方法
指定ALGORITHM=INSTANT以强制使用秒级修改字段功能(推荐)
CREATE TABLE t(a int);
SHOW CREATE TABLE t;
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE `t` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
-- 指定使用INSTANT算法快速修改字段类型
ALTER TABLE t modify COLUMN a bigint DEFAULT NULL,algorithm=INSTANT;
使用上述语句时,若返回ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY/INPLACE.
的错误,表示当前修改字段类型操作无法使用Instant算法执行。建议您查看loose_innodb_polar_instant_modify_column_enable
参数是否已开启,并仔细核对使用限制。
不指定ALGORITHM或指定ALGORITHM=DEFAULT,由PolarDB MySQL自行选择最优执行方式
当不指定ALGORITHM
或者指定为ALGORITHM=DEFAULT
时,系统将按照如下优先级选择最优的算法进行修改字段类型操作。
ALTER TABLE test.test_table MODIFY COLUMN test_column bigint, ALGORITHM=DEFAULT;
ALTER TABLE test.test_table MODIFY COLUMN test_column bigint;
PolarDB MySQL版数据库在算法选择过程中遵循以下优先级顺序:
优先使用INSTANT算法:INSTANT算法执行DDL操作时,只需要修改数据字典中的元数据,不需要修改表中数据。因此,它不受表的大小影响,整个DDL过程可以秒级完成。
其次采用INPLACE算法:大多数的INPLACE DDL在执行期间支持并发的读写操作,且支持使用并行DDL功能进行加速,对业务影响较小。
最后使用COPY算法:COPY算法需要重建整表数据,重建期间不允许执行并发写入操作,对业务影响较大。
查看秒级修改的字段信息
在INFORMATION_SCHEMA数据库中新增了INNODB_INSTANT_COLUMNS
表。该表记录了当前集群中所有曾进行过秒级修改的字段的信息(只有经过秒级修改的字段才会被收录在此表中)。该表结构如下:
SHOW CREATE TABLE INFORMATION_SCHEMA.INNODB_INSTANT_COLUMNS;
***************************[ 1. row ]***************************
Table | INNODB_INSTANT_COLUMNS
Create Table | CREATE TEMPORARY TABLE `INNODB_INSTANT_COLUMNS` (
`TABLE_ID` bigint(21) unsigned NOT NULL DEFAULT '0',
`TABLE_NAME` varchar(193) NOT NULL DEFAULT '',
`SCHEMA_NAME` varchar(193) NOT NULL DEFAULT '',
`COLUMN_NAME` varchar(193) NOT NULL DEFAULT '',
`MTYPE` int(11) NOT NULL DEFAULT '0',
`PRTYPE` int(11) NOT NULL DEFAULT '0',
`LEN` int(11) NOT NULL DEFAULT '0',
`HAS_DEFAULT` int(1) NOT NULL DEFAULT '0',
`DEFAULT_VALUE` mediumblob,
`CURRENT_VERSION` int(11) NOT NULL DEFAULT '0',
`OLD_VERSION_INFO` blob
) ENGINE=InnoDB DEFAULT CHARSET=utf8
字段说明如下:
字段名 | 描述 |
字段名 | 描述 |
TABLE_ID | 表ID。 |
TABLE_NAME | 表名。 |
SCHEMA_NAME | 库名。 |
COLUMN_NAME | 字段名。 |
MTYPE | 字段的类型信息:MYSQL_TYPE_XXX。 |
PRTYPE | 字段的PRTYPE信息。 |
LEN | 字段的长度信息。 |
HAS_DEFAULT | 是否有默认值(秒级添加的字段为 1,否则为 0)。 |
DEFAULT_VALUE | 默认值。 |
CURRENT_VERSION | 当前字段的版本信息。 |
OLD_VERSION_INFO | 该字段上所有的历史类型信息。 |
借助表INFORMATION_SCHEMA.INNODB_INSTANT_COLUMNS,您可以使用如下语句了解当前集群已被秒级修改的字段的情况:
SELECT * FROM INFORMATION_SCHEMA.INNODB_INSTANT_COLUMNS;
如果目标表使用了Instant算法进行字段类型修改操作,而后又执行了需要重建表的DDL操作(如DROP COLUMN等),系统将会删除INNODB_INSTANT_COLUMNS表中与该目标表相关的字段信息。
- 本页导读 (1)
- 前提条件
- 参数说明
- 使用限制
- 使用方法
- 指定ALGORITHM=INSTANT以强制使用秒级修改字段功能(推荐)
- 不指定ALGORITHM或指定ALGORITHM=DEFAULT,由PolarDB MySQL自行选择最优执行方式
- 查看秒级修改的字段信息