OceanBase DDL的实现以及跟MySQL的简单对比

2024年 5月 6日 86.9k 0

本文主要对 OceanBase 的DDL实现做一下简单介绍,并且通过跟MySQL DDL 的实现做对比,来帮助我们更加容易理解。

MySQL DDL 的算法

MySQL 的DDL实现算法主要有 copy、inplace和instant。

copy

copy 算法的实现方法较为简单,MySQL 会建立一个新的临时表,把源表的所有数据写入到临时表,在此期间无法对源表进行数据写入。MySQL 在完成临时表的写入之后,用临时表替换掉源表。

copy 算法会对表进行锁定,所以该种算法下的DDL属于Offline DDL,在执行DDL的时候,不能并发写操作,并且因为是copy数据,所以速度也相对较慢。

inplace

inplace 算法属于 Online DDL,根据是否需要重建表,又分为了rebuild 和 no-rebuild。

no-rebuild 不需要重建表,只需要修改表的元数据,所以速度很快。

rebuild 是需要重建表的,虽然不会创建临时表,但是实际底层的实现还是会创建新的 ibd 文件最后切换,相当于物理文件的“copy”。这个操作是 Online的,但并不是说不会锁表,其实中间会经历两次MDL 写锁,会影响写操作,只不过因为持有时间非常短,所以业务基本无感知。

OceanBase DDL的实现以及跟MySQL的简单对比-1

instant

对于一些inplace需要重建表的操作,可以通过instant来实现快速执行,因为它只需要修改数据数据字典中的内容而不再需要重建表,最典型的就是立刻加列。立刻加列完成后,当需要查询表中数据时,会将新增列的默认值追加到读取的数据后面并返回。

OceanBase DDL的实现以及跟MySQL的简单对比-2

当然,在实际业务中,大部分的MySQL DDL操作都是原生+工具结合的方式来做的,支持no-rebuild和instant的DDL使用原生,其他的DDL则使用工具,比如 pt-osc、gh-ost。

OB的DDL实现

OB的DDL包括 Online DDL 和 Offline DDL,其中 Online DDL 不影响读写,Offline DDL会堵塞写操作,直至DDL完成,这期间读操作不受影响。

Offline DDL

OB 的 Offline DDL 使用的是两表双写的方案。

两表双写方案的思路是新建一张临时的隐藏表格(对用户不可见)用于双写,同时在后台将原表的数据补全到新建的临时表格中,然后将原表重命名为一个另外的临时表格,将补全数据的临时表格重命名为原表原来的名字,最后将原表的删除。

OceanBase DDL的实现以及跟MySQL的简单对比-3

  1. 用户发起对 Src Table (T1) 的DDL操作;
  2. 停读写并新建隐藏表:停读写,新建一张隐藏表 Temp Table(T2),T2 是基于 T1 做 DDL得到的Schema,假设此时的Schema Version为S1
  3. 等事务结束:等待表格 T1 的所有分区上使用过比Schema Version S1小的事务都结束,获取一个快照点
  4. 主表补全:基于步骤3上获取的快照点,扫描表 T1 的数据,按照 T2 的Schema形式排序并写入表 T2
  5. 依赖对象数据重建:重建索引表、约束等
  6. 表名切换:将T1命名为T3,T2命名为T1,假设此时Schema Version S2
  7. 写Barrier日志:每个分区独立处理写Barrier日志
  8. 恢复读写:允许新表格上的读写
  9. 删除原表:将表T3删除

从上面的流程可以看出来,Offline DDL 的实现其实跟 MySQL 的 COPY 方式实现原理非常的像,不过OB因为是分布式数据库,所以会加入很多分布式数据库的元素以及保障,并且底层做了很多性能的优化。

Online DDL

Online DDL 主要有两种,原表上操作,比如列重命名,基本上只需要修改元数据信息,这个操作会非常的快;如果是新增索引的操作,是需要重整非原表数据的,具体的耗时跟表的数据量成正比。

拿创建全局索引流程来举例:

OceanBase DDL的实现以及跟MySQL的简单对比-4

简单来说会在创建索引开始时,拿到一个快照点,根据当前快照获取存量数据,并且排序并生成索引。全量数据获取完成后,获取增量数据,最后改成一个可读可写的状态,然后这个索引就可以用来做查询优化了。

建索引因为是ONLINE 操作,所以执行过程中是不会堵塞读写操作的。

当前版本支持的Online DDL 和 Offline DDL

下面支持的操作对应的版本是 v4.2.2 社区版本。

Online DDL操作:

OceanBase DDL的实现以及跟MySQL的简单对比-5

Offline DDL操作:

OceanBase DDL的实现以及跟MySQL的简单对比-6

DDL 执行以及进度查询

DDL 语法跟MySQL是完全相同的,这里就不过多赘述了。

查看DDL进度

OB 提供了实时 DDL 进度展示功能,通过查询 GV$SESSION_LONGOPS 视图,可以展示 DDL 操作的执行状态和进度。

mysql> select * from oceanbase.gv$session_longops\G;

各个字段含义:

  • sid:现在没有填值,为默认的 -1。
  • trace_id: OBServer 程序日志的ID,可以用该ID来搜索相关的日志文件。
  • opname:建索引时,会展示 create index 信息。
  • target:建索引时,展示正在创建的索引名。
  • svr_ip: 调度任务在哪个 OBServer 执行。
  • svr_port:调度任务在哪个 OBServer 执行。
  • start_time:索引构建开始时间,这里只精确到日期,跟 Oracle 是兼容的。
  • elapsed_seconds: 索引构建执行的时间,单位为秒。
  • time_remaining: 兼容 Oracle 的字段,暂时还没有实现剩余时间预测的能力。
  • last_update_time: 统计信息收集的时间,也是精确到日期,跟 Oracle 是兼容的。
  • message:里面包含了多个信息,ENANT_ID为租户 ID,TASK_ID为DDL 的任务 ID,STATUS 为 DDL 执行到的状态,REPLICA BUILD 指的是数据补全阶段,索引数据补全主要分为扫描主表数据,排序,写入到索引表阶段,三个阶段处理的行数分别对应于ROW_SCANNED, ROW_SORTED 和 ROW_INSERTED,因排序阶段可能会进行多轮归并,所以ROW_SORTED 的行数通常比 ROW_SCANNED 和 ROW_INSERTED 要多。

写在最后

OB因为是分布式数据库,所以DDL其实还设计很多分布式相关的底层逻辑实现,比如多副本如何调度、主备库怎么同步等等,这里就不详细介绍了。如果大家想要了解更详细的细节,可以到官网查询或者问答区咨询。

有兴趣的朋友,可以关注下微信公众号,会同步更新内容的。

OceanBase DDL的实现以及跟MySQL的简单对比-7

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论