3.1.6 ONLINE DDL
3.1.6.1 背景
- 在3.20.04.0或之前版本的dble中执行ddl,需要加表锁,若是在集群中,也会通知其他dble加上表锁,加锁期间执行对应表的SQL会报错。在ddl执行结束后dble会下发show create table 得到建表语句,得到建表语句后会解析重新生成元数据,集群中的其他dble也会执行此操作。
- 但一部分SQL其实对dble不造成影响,对dble造不造成影响的判断依据在于是否需要更改dble中表的元数据,目前dble中表的元数据只关心表的列名称,列类型,类是否为null。若这样的sql在mysql侧也是onlineDDL的,可以无需加锁,直接下发执行,例如增加索引的操作。
3.1.6.2 ONLINE DDL种类
以下穷举了MySQL 8.0中所有的online ddl以及是否在dble中支持online ddl模式。
- Index Operations
- Primary Key Operations
- Column Operations
- Generated Column Operations
- Foreign Key Operations
- Table Operations
- Tablespace Operations
- Partitioning Operations
序号 | 类别 | 操作 | 语句 | 直接下发? | 备注 |
---|---|---|---|---|---|
1 | 索引操作 | 创建或者新增二级索引 | CREATE INDEX name ON table (col_list);ALTER TABLE tbl_name ADD INDEX name (col_list); | 是 | 涉及到表的事务结束后才会执行该操作。操作期间,支持表的并发读写。 |
2 | 删除索引 | DROP INDEX name ON table;ALTER TABLE tbl_name DROP INDEX name; | 是 | 涉及到表的事务结束后才会执行该操作。操作期间,支持表的并发读写。 | |
3 | 索引重命名 | ALTER TABLE tbl_name RENAME INDEX old_index_name TO new_index_name, ALGORITHM=INPLACE, LOCK=NONE; | 否 | mysql 5.6 该操作不是online ddl | |
4 | 添加 FULLTEXT 索引 | CREATE FULLTEXT INDEX name ON table(column); | 否 | 有限制,具体参见mysql官方文档 | |
5 | 添加 SPATIAL 索引 | CREATE TABLE geom (g GEOMETRY NOT NULL); ALTER TABLE geom ADD SPATIAL INDEX(g), ALGORITHM=INPLACE, LOCK=SHARED; | 否 | 有限制,具体参见mysql官方文档 | |
6 | 修改索引类型 | ALTER TABLE tbl_name DROP INDEX i1, ADD INDEX i1(key_part,... ) USING BTREE, ALGORITHM=INSTANT; | 是 | ||
7 | 主键操作 | 新增主键 | ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE; | 否 | 主键操作过程中都需要重建表数据,代价较昂贵 |
8 | 删除主键 | ALTER TABLE tbl_name DROP PRIMARY KEY, ALGORITHM=COPY; | 否 | 该操作只允许COPY操作,过程中不支持并发dml | |
9 | 修改主键 | ALTER TABLE tbl_name DROP PRIMARY KEY, ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE; | 否 | 主键的确定在初期就应该确认好,避免在后期修改 | |
10 | 列操作 | 新增列 | ALTER TABLE tbl_name ADD COLUMN column_name column_definition, ALGORITHM=INSTANT; | 否 | dble需要重新生成表元数据 |
11 | 删除列 | ALTER TABLE tbl_name DROP COLUMN column_name, ALGORITHM=INPLACE, LOCK=NONE; | 否 | dble需要重新生成表元数据 | |
12 | 重命名列 | ALTER TABLE tbl CHANGE old_col_name new_col_name data_type, ALGORITHM=INPLACE, LOCK=NONE; | 否 | dble需要重新生成表元数据 | |
13 | 列重排序 | ALTER TABLE tbl_name MODIFY COLUMN col_name column_definition FIRST, ALGORITHM=INPLACE, LOCK=NONE; | 否 | ||
14 | 修改列数据类型 | ALTER TABLE tbl_name CHANGE c1 c1 BIGINT, ALGORITHM=COPY; | 否 | 执行期间,不允许dml | |
15 | 加长 VARCHAR 长度 | ALTER TABLE tbl_name CHANGE COLUMN c1 c1 VARCHAR(255), ALGORITHM=INPLACE, LOCK=NONE; | 否 | 涉及到dble的表元数据 | |
16 | 给列设置默认值 | ALTER TABLE tbl_name ALTER COLUMN col SET DEFAULT literal, ALGORITHM=INSTANT; | 是 | ||
17 | 删除列的默认值 | ALTER TABLE tbl ALTER COLUMN col DROP DEFAULT, ALGORITHM=INSTANT; | 是 | ||
18 | 修改自增值 | ALTER TABLE table AUTO_INCREMENT=next_value, ALGORITHM=INPLACE, LOCK=NONE; | 否 | 若是分片节点,给每个节点设置成相同的自增值没有意义 | |
19 | 列可以为NULL | ALTER TABLE tbl_name MODIFY COLUMN column_name data_type NULL, ALGORITHM=INPLACE, LOCK=NONE; | 否 | 涉及到dble的表元数据 | |
20 | 列不可以为NULL | ALTER TABLE tbl_name MODIFY COLUMN column_name data_type NOT NULL, ALGORITHM=INPLACE, LOCK=NONE; | 否 | 涉及到dble的表元数据 | |
21 | 修改 ENUM 或 SET列的定义 |
CREATE TABLE t1 (c1 ENUM('a', 'b', 'c')); ALTER TABLE t1 MODIFY COLUMN c1 ENUM('a', 'b', 'c', 'd'), ALGORITHM=INSTANT; | 否 | 不常用 | |
22 | 外键操作 | 新增外键 | ALTER TABLE tbl1 ADD CONSTRAINT fk_name FOREIGN KEY index (col1) REFERENCES tbl2(col2) referential_actions; | 否 | dble中的表会跨多实例,表与表之间建立外键无实际意义 |
23 | 删除外键 | ALTER TABLE tbl DROP FOREIGN KEY fk_name; | |||
24 | Generated列操作 | 新增 Generated 列 | ALTER TABLE t1 ADD COLUMN (c2 INT GENERATED ALWAYS AS (c1 + 1) STORED), ALGORITHM=COPY; | 否 | 相当于新增一列 |
25 | 修改 Generated 列顺序 | ALTER TABLE t1 MODIFY COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED FIRST, ALGORITHM=COPY; | |||
26 | 删除 Generated 列 | ALTER TABLE t1 DROP COLUMN c2, ALGORITHM=INPLACE, LOCK=NONE; | |||
27 | 新增 VIRTUAL 列 | ALTER TABLE t1 ADD COLUMN (c2 INT GENERATED ALWAYS AS (c1 + 1) VIRTUAL), ALGORITHM=INSTANT; | |||
28 | 修改 VIRTUAL 列顺序 | ALTER TABLE t1 MODIFY COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) VIRTUAL FIRST, ALGORITHM=COPY; | |||
29 | 删除 VIRTUAL 列 | ALTER TABLE t1 DROP COLUMN c2, ALGORITHM=INSTANT; | |||
30 | 表空间操作 | 否 | 更偏向MySQL运维测 | ||
31 | 表分区操作 | 否 | dble 分库分表的功能不涉及表分区,不需要支持 |
3.1.6.3 限制
- dble 使用阿里的druid作为解析器,因此有些online ddl语句的 “ALGORITHM=INPLACE, LOCK=NONE” 不被支持,详情参考:https://github.com/alibaba/druid/issues/3750