在MySQL中,执行Online DDL时,提供ALGORITHM参数选项决定了在线DDL操作的构建方式。这个选项可以是 INPLACE、COPY 或 INSTANT。
- INPLACE: 尽可能在不复制表的情况下进行更改。这是最快的选项,但不是所有的更改都支持这种方式。
- COPY: 通过创建一个新表,复制旧表的数据到新表,然后删除旧表并替换为新表来完成更改。这种方式总是可用的,但比INPLACE 更慢,因为它涉及到数据的复制。
- INSTANT:即使添加,不影响表的数据,只更改元表信息。
1.在线DDL操作,对VARCHAR不同长度的影响
下面了解下,在同一个字段,同一个类型,在不同字符集下超过一定长度之后,原先的ALGORITHM不适应情况。示例两张表testa(utf8mb4字符集),testb (utf8字符集):
示例1: utf8mb4字符集表。varchar(63) 变更 varchar(64)
#utf8mb4字符集表:
mysql>CREATE TABLE `testa` (
`a` bigint NOT NULL AUTO_INCREMENT,
`b` varchar(80) DEFAULT NULL,
`c` varchar(60) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
#c字段变更长度为63,ALGORITHM=INPLACE 成功:
mysql> alter table testa modify column c varchar(63), ALGORITHM=INPLACE;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
#c字段变更长度为64,ALGORITHM=INPLACE 失败:
mysql> alter table testa modify column c varchar(64), ALGORITHM=INPLACE;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
实例2:utf8字符集表。varchar(85)变更 varchar(86)
#utf8字符集表:
mysql> CREATE TABLE `testb` (
`a` bigint NOT NULL AUTO_INCREMENT,
`b` varchar(80) DEFAULT NULL,
`c` varchar(60) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#b字段变更长度为85,ALGORITHM=INPLACE 成功:
mysql> alter table testb modify column b varchar(85), ALGORITHM=INPLACE;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
#b字段变更长度为86,ALGORITHM=INPLACE 失败:
mysql> alter table testb modify column b varchar(86), ALGORITHM=INPLACE;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
可以总结如下结论:
当超过一定长度之后,字符集编码的时候,需要更长的字节长度提供。
备注:
编码用于规定每个字符用 1 字节还是多字节存储,用哪些字节存储,简单说就是字符与二进制的对应关系。1字节有8位,每位可以是0或1,对应数据范围0-255,可以表示 256 种不同的码。
2.在线DDL操作,对VARCHAR不同长度的官方说明
在MySQL中,最常见的两种字符集utf8 与utf8mb4中每个字符最多分别占用3与4字节。【上述示例中utf8的85长度和utf8mb4的64长度超过 255字节】
官方介绍中,“The byte length of a VARCHAR column is dependant on the byte length of the character set.”VARCHAR列的字节长度取决于字符集的字节长度。
就是说
- 对VARCHAR列大小为0到255字节的VARCHAR列,需要一个长度字节来对值进行编码。对于大小为256字节或以上的VARCHAR列,需要两个长度字节。因此,就地ALTER TABLE仅支持将VARCHAR列大小从0增加到255字节,或从256字节增加到更大的大小。就地ALTER TABLE不支持将VARCHAR列的大小从小于256字节增加到等于或大于256字节。在这种情况下,所需长度字节的数量从1变为2,这仅由表副本(ALGORITHM=copy)支持。
- 不支持使用就地ALTER TABLE减小VARCHAR大小。减小VARCHAR大小需要一个表副本(ALGORITHM=copy)。
示例3:utf8mb4字符集表。varchar(256) 变更 varchar(200)
mysql> CREATE TABLE `testc` (
`a` bigint NOT NULL AUTO_INCREMENT,
`d` varchar(256) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
#d字段变更长度为200,ALGORITHM=INPLACE 失败:
mysql]> ALTER TABLE testc CHANGE COLUMN d d VARCHAR(200), ALGORITHM=INPLACE;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
总结:
MySQL中VARCHAR的长度255字节是一个分界线。在通过官方Online DDL执行是需要注意ALGORITHM的变化。以减少对生产环境的影响。