本文介绍了对冷数据进行DDL的操作方法以及优化方法。
前提条件
DDL执行算法
PolarDB MySQL版冷数据支持以下2种DDL执行算法:
INSTANT算法: 使用INSTANT算法执行DDL操作时,只需要修改数据字典中的元数据,不需要修改或复制存量数据,也不需要重建表。因此其不受表的大小影响,整个DDL过程可以秒级完成。
COPY算法:当使用COPY算法执行DDL操作时,需要将表中所有的数据复制到新表中。在数据复制期间,会持有原表的SNW(SHARED_NO_WRITE)锁。因此,在执行DDL操作期间仅支持读操作,不允许执行并发写入操作,对业务影响较大。
为了使用指定算法执行DDL语句,您可以指定ALGORITHM字段,可选的值有DEFAULT、INSTANT和COPY。当DDL操作不支持该算法时,会立即返回报错。
通常来说,INSTANT算法比COPY算法代价更低,执行影响更小。当用户不通过ALGORITHM手动指定DDL使用的算法时,PolarDB MySQL版会自动优先选择INSTANT算法,其次才考虑使用COPY算法。因此,本文详细介绍INSTANT算法。
INSTANT算法使用说明
8.0.2.2.23版本支持了OSS冷数据表的元数据(OSS META)能力。只有当表开启OSS META时,才可以支持INSTANT DDL,否则只能支持COPY DDL。 使用方法如下:
查看当前表是否开启OSS META。
通过
show create table
命令,可以查看当前表是否开启了OSS META。如果返回结果中有OSS META=1 ,则说明当前表开启了OSS META。show create table t \G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` varchar(1000) DEFAULT NULL ) /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ 1 row in set (0.00 sec)
老化场景下增加OSS META。
无论是InnoDB单表老化为OSS外表,还是InnoDB分区表归档至OSS外表,或是InnoDB表归档至OSS分区,在创建新的OSS外表时,都是通过系统变量 use_oss_meta来控制当前创建的OSS外表(分区)是否使用OSS META管理元数据。
当系统变量use_oss_meta为ON时,例如:
show variables like "use_oss_meta"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | use_oss_meta | ON | +---------------+-------+ 1 row in set (0.03 sec)
此时,归档至OSS外表会带有OSS META标记:
alter table t engine = csv storage oss; Query OK, 3 rows affected (2.13 sec) Records: 3 Duplicates: 0 Warnings: 0 show create table t \G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` varchar(1000) DEFAULT NULL ) /*!50100 */ /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ 1 row in set (0.00 sec)
alter table t1 change partition p0 engine = orc; Query OK, 0 rows affected (1.95 sec) Records: 0 Duplicates: 0 Warnings: 0 show create table t1 \G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `order_time` datetime DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020223 OSS META=1 */ CONNECTION='default_oss_server' /*!99990 800020205 PARTITION BY RANGE COLUMNS(id) (PARTITION p0 VALUES LESS THAN (10) ENGINE = ORC, PARTITION p1 VALUES LESS THAN (20) ENGINE = InnoDB, PARTITION p2 VALUES LESS THAN (30) ENGINE = InnoDB, PARTITION p3 VALUES LESS THAN (40) ENGINE = InnoDB, PARTITION p4 VALUES LESS THAN (50) ENGINE = InnoDB, PARTITION p5 VALUES LESS THAN (60) ENGINE = InnoDB, PARTITION p6 VALUES LESS THAN (70) ENGINE = InnoDB, PARTITION p7 VALUES LESS THAN (80) ENGINE = InnoDB, PARTITION p8 VALUES LESS THAN (90) ENGINE = InnoDB, PARTITION p9 VALUES LESS THAN (100) ENGINE = InnoDB, PARTITION p10 VALUES LESS THAN (110) ENGINE = InnoDB) */ 1 row in set (0.00 sec)
对没有OSS META的表添加META。
可以通过
repair
命令对没有META的表额外增加OSS META。repair table t; +--------+--------+----------+----------+ | Table | Op | Msg_type | Msg_text | +--------+--------+----------+----------+ | test.t | repair | status | OK | +--------+--------+----------+----------+ 1 row in set (0.84 sec) show create table t \G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` varchar(1000) DEFAULT NULL ) /*!50100 */ /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ 1 row in set (0.00 sec)
说明在repair期间会持有表的X锁,当前表无法查询和修改。repair实际时间与表的大小有关。
关闭当前表的OSS META功能。
可以通过
disable
命令关闭当前表的META。alter table t disable oss meta; Query OK, 0 rows affected (0.04 sec) Records: 0 Duplicates: 0 Warnings: 0 show create table t \G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` varchar(1000) DEFAULT NULL ) /*!50100 */ /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ 1 row in set (0.00 sec)
关闭后,表上不会显示OSS META标记。
说明执行
disable
命令关闭META后,无需重启,即可生效。
DDL行为特征
COLUMN操作
操作 | 重建表 | 仅修改元数据 |
增加列 | 否1 | 是1 |
删除列 | 是 | 否 |
重命名列 | 否 | 是 |
重排序列 | 是 | 否 |
设置列的默认值 | 否 | 是 |
修改列注释 | 否 | 是 |
修改列类型 | 是 | 否 |
扩展VARCHAR长度 | 否 | 是 |
将UTF8mb3字符集修改为UTF8mb4字符集 | 否2 | 是2 |
删除列默认值 | 否 | 是 |
修改auto-increment值 | 否 | 是 |
变更某列为NULL | 是 | 否 |
变更某列为非NULL | 是 | 否 |
修改ENUM/SET列的定义 | 否 | 是3 |
秒级加字段功能仅支持将列添加至表的末尾。同时,需要当前表开启OSS META 。当表未指定主键时,需要将参数
implicit_primary_key
的值设置为OFF,以避免在执行秒级加字段操作时因表的最末尾的隐式主键列导致加列操作失败。如果集群不支持使用秒级加字段功能,增加字段将使用COPY方式执行DDL。此时需要进行全表重建,重建期间允许并发读操作。当满足以下条件时,将列的字符集从UTF8mb3修改至UTF8mb4仅修改元数据,无需修改数据。否则,需要使用COPY算法进行表重建,且重建期间全程锁表,目标表只能读,不能执行写入操作。
列类型为CHAR、VARCHAR、ENUM以及TEXT类型。
修改的列上不存在任何索引。
字符集转换前后,列的最大存储长度均小于256或均大于255。
您可以通过指定ALGORITHM=INSTANT 来强制使用非重建表的方式执行DDL,如果需要使用COPY算法才能执行时,会立刻返回报错。示例如下:
ALTER TABLE test modify column b char(1) CHARACTER SET utf8mb4 default null,algorithm = INSTANT; ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE.
仅当数据类型的存储大小不发生改变,且向ENUM或SET的末尾追加元素时,才可以仅修改元数据,不重建整张表。否则需要使用COPY算法进行表重建。
Table操作
操作 | 重建表 | 仅修改元数据 |
开启META | 是 | 否 |
关闭META | 否 | 是 |
声明Character Set | 否 | 是 |
转换Character Set | 是 | 否 |
重命名表 | 否 | 是1 |
修改表注释 | 否 | 是 |
重命名表不会全部重写表的数据,但是会对该表对应的OSS数据文件做RENAME操作,因此rename速度和表大小呈正相关,略慢于其他的INSTANT操作。