AntDB 基于 WAL 日志的 DML 数据闪回实现
01 概述
AntDB 数据库是一款国产自研的 MPP 架构的分布式数据库,高度兼容 Oracle 语法,在通信、金融、交通等多个行业应用广泛。用户在使用 AntDB 数据库的过程中,经常由于误操作、应用程序 Bug 等,导致了误删数据或者误更新数据,影响业务正常使用。误删数据不是某个数据库的个例,几乎所有的数据库都会遇到类似问题,并且大多数数据库都会提供一个【数据闪回】的工具,利用该工具可以快速恢复误操作数据。
根据误操作类型,可以将数据闪回分为 DML 数据闪回和 DDL 数据闪回。DML 数据闪回主要针对 insert、update、delete 场景,DDL 数据闪回主要针对 drop table、truncate table 场景,而 AntDB 能够支持 DML 和 DDL 这两种数据闪回。本文将主要介绍 DML 数据闪回的实现细节。
02 方案选型
AntDB 的 DML 数据闪回有两种主流的实现方式。第一种是基于 WAL 日志的数据闪回,它有两个前提条件,表结构未发生改变并且保留足够的 WAL 日志,结合表结构元数据,解析 WAL 日志进行数据恢复。第二种基于 MVCC 机制实现,AntDB 更新、删除记录并不是真正的删除,而是生成新的记录,并将旧的记录进行标记,从而在 vacuum 执行前,能够利用记录的多版本信息以及事务提交信息找回旧的记录。两种方式都有各自的适用场景及弊端。
基于 WAL 日志的数据闪回需要保留大量的 WAL 日志文件,这会占用大量存储空间。在 WAL 文件数量较多时,需要遍历所有 WAL 日志,耗时较长,并且表不能做 DDL 操作。它的优点是逻辑简单,在技术实现上较容易,且社区有现成的开源实现可供参考。
而基于 MVCC 的机制则需要保证 vacuum 不会清除不用的多版本元组,vacuum 相关参数需要谨慎设置。由于多版本元组不能及时清除释放,同样也会带来占用大量空间的问题。但相对来说,基于 MVCC 的实现方式更复杂,需要更深层地修改内核代码,因此在调研完两种方案的优缺点后,我们选择基于 WAL 日志的 DML 数据闪回实现方式。
03 实现原理
3.1 WAL 日志组成
WAL 日志由一个个 Record 组成,Record 分为不同的类型,如图 1 所示:
图 1 WAL Record 类型
AntDB 的底层存储是堆表。从数据闪回的角度,只需要关心 Heap 表以及事务相关的类型,其他的 Record 类型不影响数据闪回的结果。事务相关的 Record 记录了事务的状态,commit 或者 abort,abort 状态的事务数据不需要闪回,因此只需要关心 commit 状态的事务。
Heap 类型的 Record,记录了 insert、update、delete 操作产生的事务数据,根据 DML 类型可以再进行细分,如图 2 所示:
图 2 Heap 子类型
3.2 解析流程
DML 数据闪回支持按表名闪回、按时间区间闪回、按事务号 XID 闪回、按 LSN 区间闪回。从内部实现上来看,这些闪回方式最终都会转换为一个 LSN 区间,包含起始 LSN 和结束 LSN,如果指定了表名,则会在解析 WAL Record 记录时按表名进行过滤。图 3 中的 lsn3~lsn4 即为解析的 LSN 区间。
图 3 LSN 区间示意图
基于 WAL 日志的数据闪回需要设置两个重要的参数:wal_level 和 full_page_writes。第一种参数 wal_level 需要设置为 replica 或者 logical,minimal 级别保存的信息较少,不足以恢复数据。第二种参数 full_page_writes 需要设置为 on。AntDB 每次 checkpoint 之后 page 的首次更新,都会将 page 页面完整地写入到 WAL 日志中。这种机制在宕机等异常场景下能够保证数据不丢失,比如在脏页刷盘时发生崩溃,并且在恢复时发现原始页面损坏,那么这时就可以通过 WAL 里面的 full page 进行恢复。Full Page Write(简称 FPW)页面保存了页面的原始数据,这对于解析 WAL 数据至关重要,一些 Record 记录它本身的数据对于解析出完整的正向 SQL 和反向 SQL 并不充分,需要依赖 FPW 提供的原始数据。FPW 在一次 checkpoint 之后才会写,在闪回数据时,选择的 LSN 区间应当在一个可用的 checkpoint 之前。在代码实现上,即使 LSN 区间在 checkpoint 之后,也会往前搜索,直到搜索到一个可用的 checkpoint。
在确定了 WAL 的 LSN 区间后,就可以对此区间内的 WAL Record 做解析。根据不同的 Record 类型,结合元数据、FPW,拼接出原始 SQL 以及闪回 SQL,记录到结果表中。整体解析流程如图 4 所示:
图 4 WAL 解析流程图
在解析 WAL 日志的过程中,解析程序以事务作为基本单位进行解析。一个事务对应一个 TransactionEntry 对象,一个事务可以包含多个 SQL 语句,每个 SQL 语句对应 change 链表的一个元素。在事务提交时,将 change 链表的所有元素拼接出正向 SQL 文本,以及反向 SQL 文本。
3.3 toast 表解析
WAL 解析过程中的一个难点是 toast 表。AntDB 对于大字段的表,使用 toast 机制进行存储。toast 英文全称为 The OverSized Attribute Storage Technique(超尺寸字段存储技术)。toast 机制的主要思路是使用额外的 toast 表来存储大字段数据,避免一条记录跨越多个 page 页面,在原始的字段存储区内存储对应的 toast 表的 oid 以及其数据行的 chunk_id。
pg_class 表的 reltoastrelid 字段记录的就是其对应的 toast 表的 oid,toast 表的表名后缀为其父表的 oid。举例来说,一张普通表 t,oid 为 10022077,reltoastrelid 为 10022080,表 t 对应的 toast 表为:pg_toast_10022077,oid 为 10022080。普通表与 toast 表在 pg_class 中通过字段 relkind 进行区分,普通表为 'r',toast 表为 't'。
对一个涉及大字段的普通表执行 DML 操作,该表与其对应的 toast 表的 wal 写入顺序如下:
insert 操作,先插入 toast 表记录,再对普通表进行写入
update 操作,先插入 toast 表记录,再删除 toast 表记录,最后更新普通表
delete 操作,先删除普通表记录,再删除 toast 表记录
以上可以看出,insert 与 update 都是先对 toast 表进行操作,然后对普通表操作,而 delete 则相反,这一点对于处理 delete 场景下的 toast 表数据闪回至关重要。
3.4 闪回数据存储
WAL 日志解析拼接出来的 SQL 将会存储在表中,表结构如表 1 所示:
表 1 解析结果表
op_text 为原始的 SQL 语句,undo_text 为闪回的 SQL 语句。如果想快速恢复数据,则需要将 undo_text 导出,按时间逆序执行一次,即可恢复这段时间的数据。
04 使用示例
创建一张表 t,插入 3 条记录,然后再删除表 t 的所有记录,如图 5 所示:
图 5 误删数据操作示意图
执行 DML 数据闪回函数 wal2sql,指定表名 t 为参数,执行完成后从 wal2sql_contents 表中能够看到 DML 数据闪回的结果,op_text 表示原始的 SQL,undo_text 表示反向的闪回 SQL,如图 6 所示:
图 6 闪回数据操作示意图
05 改进与提升
AntDB DML 数据闪回工具在开发过程中,解决了一系列涉及具体场景的问题,主要包括 toast 表解析、子事务解析、Oracle 兼容性问题;同时还解决了涉及具体场景的性能问题,如海量表场景下的性能问题、大数据量场景下的性能问题。AntDB DML 数据闪回工具不仅支持 AntDB 单机版本,还支持 AntDB 分布式集群场景下的数据闪回。
(1)toast 表解析问题主要是由于 delete 场景下原表与 toast 表在处理顺序上与 insert 和 update 不同,此处需要特殊处理,否则会导致 toast 表在 delete 场景下解析结果不正确。
(2)子事务是 AntDB 使用较多的一个场景,子事务的解析需要严格考虑父子事务之间的关系以及事务提交状态,解析子事务时应当保证子事务的准确性,不能出现丢失部分子事务的情况。
(3)Oracle 兼容是 AntDB 的一大特色,AntDB 高度兼容 Oracle 语法和存储类型,比如 Oracle 类型 rowid。数据闪回需要考虑 Oracle 兼容性,保证在 Oracle 语法下创建的表以及生成的数据能够正确闪回。
(4)数据闪回需要支持分布式集群,AntDB 分布式架构下数据分散存储在不同的数据节点上,DML 数据闪回能够支持所有数据节点的数据闪回。在使用方法上只需要连接到任意一个 CN 节点执行数据闪回命令,与单机版本在使用方法上完全一致,做到了简单易用。
(5)数据闪回的性能提升,主要包括海量表场景下的执行性能提升,比如数据库中包含超过 100 万张以上的表,元数据数量巨大,此场景要保证解析性能不会出现较大的下降。此外,大事务场景下的执行性能优化,1 个事务包含大量 SQL 以及大字段涉及大量 toast 表的解析,都需要保证性能不会有太大的损耗。
06 总结
本文介绍了 AntDB 基于 WAL 日志实现 DML 数据闪回的一种方式,讨论了其实现原理,并在社区开源实现的基础上做了大量改进和提升。数据闪回是一个非常重要的工具,虽然平时使用频率不高,但在紧急关头能够挽救数据。数据闪回不限于一种方式,AntDB 在未来将探索基于 MVCC 多版本控制的数据闪回,为数据恢复提供更多实现路径。
关于 AntDB 数据库
AntDB 数据库始于 2008 年,在运营商的核心系统上,为全国 24 个省份的 10 亿多用户提供在线服务,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔电信核心交易,保障系统持续稳定运行近十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。
评论