在线DDL(Online Data Definition Language,Online DDL)是指数据库系统可以允许DDL操作与其他事务并发执行,减少对表的锁定时间,提高了数据库的并发性能,本文将详细介绍Online DDL的执行特性。
前提条件
Online DDL特性概述
在PolarDB-X中存在两类DDL:
物理执行:直接下推到存储节点执行物理DDL,如
CREATE LOCAL INDEX
、ALTER/ADD COLUMN
、CREATE/DROP TABLE
,此类DDL的计算节点只进行分片级的物理语句转发、协调和元信息管理,其实现原理及Online特征与MySQL DDL基本保持一致。
逻辑执行:由计算节点自行实现完整的DDL执行操作,如
GLOBAL INDEX
、CREATE/DROP PARTITION
、CREATE/DROP PRIMARY KEY
、无锁变更列类型(OMC),此类DDL的实现方式为实例中冗余一份临时表用于回填存量数据和追赶增量数据,然后切流到新表。计算节点处理完整的数据回填、增量多写和元信息管理流程,此类DDL均不会锁表。
根据对业务SQL的影响,可以从以下三个维度进一步分析Online DDL的特性:
是否锁表:
Online DDL只会在切表时秒级阻塞DML操作,其余执行时间均可执行DML操作。
非Online DDL则会在执行过程中全程锁表,不可进行DML操作。
是否需要回填数据:
对于只涉及元数据修改的DDL(如
INSTANT ADD COLUMN
、RENAME TABLE
等),此类操作秒级时间内即可完成,无需回填数据。对于
DROP TABLE
、DROP INDEX
,此类操作只需要修改元数据和删除相关物理文件,执行时间较短,无须回填数据。对于非
INSTANT
操作、非删除表、非删除索引的DDL,需要在物理执行或者逻辑执行过程中拷贝原有数据,写入新的聚簇或者二级索引,在执行过程中占用一定量的集群资源,执行时间与表的数据量、并发度、实例资源规格等相关。
是否需要同步多写:
对于逻辑执行且需回填数据的DDL,在数据回填期间需要将在线DML流量同步多写到目标临时表上,可能与回填流量之间出现数据冲突,并且由于多写采用分布式事务保证原子性,下推执行的DML将转变为逻辑执行,在线流量的性能将出现一定程度的下跌。PolarDB-X对于包括
MOVE/SPLIT PARTITION
、无锁变更列类型(OMC)、REBALANCE
在内的逻辑执行DDL均实现了异步多写优化,将DML的多写流量缓存到数据回填阶段后异步执行,以最大的降低多写冲突和性能下降的持续时间(在本文Online DDL特性详述章节中将对此类DDL标注“是否支持异步多写优化”属性)。对于物理执行、回填数据且不锁表的DDL,即对于存储节点的原生Online DDL,均已默认通过Online Log实现了原生的异步多写(在本文Online DDL特性详述章节中将不对此类DDL标注“是否支持异步多写优化”属性)。
其他类型DDL不需要多写。(在本文Online DDL特性详述章节中将不对此类DDL标注“是否支持异步多写优化”属性)。
Online DDL特性详述
在通过DDL语句进行表操作和列操作时,特别是在MODIFY COLUMN
和CHANGE COLUMN
语句中,需要声明完整的列属性,避免遗漏属性从而造成非预期的列修改行为。
索引操作
操作类型 | 是否逻辑执行 | 是否锁表 | 是否重建表 | 是否需要回填数据 | 是否支持异步多写优化 |
创建局部二级索引 | No | No | No | Yes | - |
删除局部二级索引 | No | No | No | No | - |
重命名局部二级索引 | No | No | No | No | - |
创建全局二级索引 | Yes | No | Yes | Yes | No |
删除全局二级索引 | Yes | No | No | No | - |
重命名全局二级索引 | Yes | No | No | No | - |
表操作
操作类型 | 是否逻辑执行 | 是否锁表 | 是否重建表 | 是否需要回填数据 | 是否支持异步多写优化 |
修改(ROW_FORMAT) | No | No | Yes | Yes | - |
OPTIMIZE TABLE | No | No | Yes | Yes | - |
重命名表 | No | No | No | No | - |
修改表的默认字符集 | No | No | Yes | Yes | - |
转换字符集 | No | Yes | Yes | Yes | - |
清理表(TRUNCATE TABLE WITHOUT GSI) | No | No | Yes | No | - |
清理带有GSI的表(TRUNCATE TABLE WITH GSI) | Yes | No | Yes | No | - |
分区操作
操作类型 | 是否逻辑执行 | 是否锁表 | 是否重建表 | 是否需要回填数据 | 是否支持异步多写优化 |
迁移分区 | Yes | No | Yes(仅重建相应分区) | Yes | Yes 说明
|
分裂分区 | Yes | No | Yes(仅重建相应分区) | Yes | |
合并分区 | Yes | No | Yes(仅重建相应分区) | Yes | No |
增加分区 说明
| Yes | No | No | No | - |
删除分区 说明
| Yes | No | No | No | - |
重组分区 | Yes | No | Yes(仅重建相应分区) | Yes | No |
清空分区 | Yes | No | No | No | - |
重命名分区 | Yes | No | No | No | - |
修改分区 | Yes | No | Yes(仅重建相应分区) | Yes | No |
表组和表级分区操作的Online特性完全相同,均可参照上表。
Sequence变更操作
操作类型 | 是否逻辑执行 | 是否锁表 | 是否重建表 | 是否需要回填数据 | 是否支持异步多写优化 |
创建Sequence | Yes | No | No | No | - |
删除Sequence | Yes | No | No | No | - |
修改Sequence属性 | Yes | No | No | No | - |
转换Sequence类型 | Yes | No | No | No | - |
一般列操作
列操作分为一般列操作(即非主键、非分区键、非生成列的列操作)、主键和分区键变更操作、生成列操作,可通过SHOW FULL CREATE TABLE TABLE_NAME
查看完整的列属性,以确定列操作所属的范畴。
操作类型 | 是否逻辑执行 | 是否锁表 | 是否重建表 | 是否需要回填数据 | 是否支持异步多写优化 |
加列(说明请参见说明一) | No | No | Yes | Yes | - |
减列 | No | No | Yes | Yes | - |
重命名列 | No | No | No | No | - |
修改列的顺序 | No | No | Yes | Yes | - |
修改列的默认值 | No | No | No | No | - |
删除列的默认值 | No | No | No | No | - |
修改列的数据类型 | No | Yes | Yes | Yes | - |
No | No | No | No | - | |
延长char类型列的长度(说明请参见说明三) | No | Yes | Yes | Yes | - |
修改列为NULL | No | No | Yes | Yes | - |
修改列为NOT NULL 说明 当 | No | No | Yes | Yes | - |
PolarDB-X对于加列操作单独支持INSTANT算法,可在仅修改元数据的情况下执行。对于部分改列操作,可采用逻辑执行在线完成,在分别显式声明
ALGORITHM=INSTANT
和ALGORITHM=OMC
前提下,其Online执行特征如下:操作类型
是否逻辑执行
是否锁表
是否重建表
是否需要回填数据
是否支持异步多写优化
No
No
No
No
-
在线变更列类型
Yes
No
Yes
Yes
Yes
延长
VARCHAR
类型列的长度,PolarDB-X在5.7版本的存储节点(8.0版本存储节点不支持)上默认支持INPLACE
算法,其长度在255个字节以下时长度需要一个字节存储,256个字节及以上需要两个字节存储,如果该列长度由小于等于255字节延长至大于等于256字节,则不支持仅修改元数据,反之则支持仅修改元数据。操作类型
是否逻辑执行
是否锁表
是否重建表
是否需要回填数据
是否支持异步多写优化
延长
VARCHAR
类型列的长度且字节长度跨越256No
No
Yes
Yes
-
延长
CHAR
列长度操作,PolarDB-X在5.7版本的存储节点(8.0版本存储节点不支持)上默认支持INPLACE
算法,其Online执行特征如下:操作类型
是否逻辑执行
是否锁表
是否重建表
是否需要回填数据
是否支持异步多写优化
延长
CHAR
类型列的长度No
No
Yes
Yes
-
主键与拆分列变更操作
操作类型 | 是否逻辑执行 | 是否锁表 | 是否重建表 | 是否需要回填数据 | 是否支持异步多写优化 |
添加主键 | Yes | No | Yes | Yes | No |
删除原有主键并添加新主键 | Yes | No | Yes | Yes | No |
修改拆分方式、分区数或者拆分字段 | Yes | No | Yes(重建变更拆分的GSI或者主表) | Yes | No |
修改涉及GSI或者主表拆分列的定义 | Yes | No | Yes(重建以变更列为拆分键的GSI或者主表) | Yes | No |
生成列操作
操作类型 | 是否逻辑执行 | 是否锁表 | 是否重建表 | 是否需要回填数据 | 是否支持异步多写优化 |
增加虚拟列(VIRTUAL Column) | No | No | No | No | - |
删除虚拟列(VIRTUAL Column) | No | No | No | No | - |
增加存储列(STORED Column) | No | Yes | Yes | Yes | - |
删除存储列(STORED Column) | No | No | Yes | Yes | - |
增加逻辑列(LOGICAL Column) | Yes | No | Yes | Yes | No |
删除逻辑列(LOGICAL Column) | Yes | No | Yes | Yes | - |
如何控制online执行特性
PolarDB-X支持通过下面的方式指定online执行特征:
对于加列,可通过声明ALGORITHM=INSTANT指定采用intant add column方式。
对于在线修改列,可以通过声明ALGORITHM=OMC方式指定采用逻辑执行方式。
对于逻辑执行的DDL, 默认均为online执行方式,不需要任何特殊声明。
对于物理执行的一般列操作和本地索引操作DDL,可通过声明ALGORITHM=INPLACE指定online执行方式,如不支持则会直接报错,如支持则会直接执行。