作者:攒叶
备份背景
PolarDB-X 分布式数据库,采用集中式和分布式一体化的架构,Data Node 节点可以按照业务的发展和规模的扩大,逐步从集中式,在线平滑的进行水平拆分,扩展到分布式,以线性扩展容量。
数据库的备份恢复,承当了重要的数据安全的保障,按照数据保护和容灾的需求,PolarDB-X 提供了多样化的能力,支持任意时间点的备份恢复(简称 PITR),更多技术细节可以访问:《PolarDB-X 数据库的备份恢复》。
如上图所示,展示了 PolarDB-X 在 PITR 恢复的情况,通过全量备份 + 增量的 binlog 组合可以满足任意时间点的恢复诉求。
另外,PolarDB-X 的数据节点 DN 作为多副本架构,日常的主机运维动作,也会触发副本的动态搬迁、重建等,此时需要依赖备库重搭技术,先通过主库做一次全量备份,通过多副本 Consensus Log 来增量追平副本数据。
本文重点要介绍全量备份的设计,作为承担在线数据存储的 DN 节点,按照数据保护和容灾的需求,DN 需要支持灵活定制周期策略的备份策略。同时,PolarDB-X 能够处理和存储庞大的数据规模,备份这些数据量(例如高达 20TB 大小的数据集),如果想在更短的时间内完成备份(比如 3~4 小时),这样的备份 SLA 需要在在线业务影响、并行策略上有更多的优化。
传统 MySQL 生态的备份挑战
开源 MySQL, 采用 InnoDB 存储引擎保存数据,基于传统的 WAL 架构,其使用 redo log 物理日志来记录数据变更。 Server 层采用 Binary log 作为逻辑日志,记录了数据库实例的变更日志,包括事务型数据修改,非事务型数据修改,结构修改等所有数据库变化,其承担了三个重要的作用:
1.两阶段提交协调日志
MySQL多存储引擎的结构,Binlog 承担了2PC的 coordinator 的职责,参与两阶段提交和恢复流程。
2.数据变更日志
Binlog 记录了数据库实例的所有变更,可以通过变更日志replay一个逻辑 image,构建多类型 cluster。
3.执行集合日志
Binlog 记录了变更的唯一标识 Global Transaction Identifier 即 GTID,用于构建 Executed 集合。
如何确保 Binary log 和 InnoDB 存储引擎的备份一致性,构成了挑战。由于最终要维护 Binlog 和存储引擎参与方的一致性,导致需要一个逻辑时间点,而一般逻辑时间点需要全局 global lock 来实现,这会严重影响在线实例的运行,继而影响用户业务。
Lizard 无锁全量备份设计
PolarDB-X 存储引擎,自研了 Lizard 分布式事务系统,来替换传统的 InnoDB 单机事务系统。针对 InnoDB 事务系统的弊端,Lizard 事务系统,分别设计了 SCN 单机事务系统和 GCN 分布式事务系统来解决这些弊端,有效的支撑分布式数据库能力。
同时,PolarDB-X 在 Lizard 事务引擎的基础上,相比于传统 MySQL 的物理备份的局限性,引入新设计的 Lizard 无锁备份,让备份过程对用户业务透明,真正做到无感。
Lizard 无锁备份的核心,即放弃物理备份过程中的 Binlog 备份,只保留存储引擎参与方的备份,而 Binlog 的三个最重要的职责:
1.两阶段提交协调日志
所有一阶段 prepare 状态的存储引擎参与方,统一按照 rollback 处理。
2.变更日志
DN 在使用备份集恢复新实例的时候,强制以 follower 或者 learner 角色加入 cluster,接收由集群 leader 使用 X-Paxos 协议发送的 Binlog 日志。
3.执行集合
PolarDB-X DN 新引入了一个组件,即 Lizard Transaction Slot (LTS),作为一个新的强制的参与方引擎,参与到MySQL 所有的变更,包括事务型,非事务型,结构变化等,Gtid Executed 执行集合由 LTS 来维护,以实现幂等控制。
通过以上的替代,覆盖 Binlog 所承担的职责,实现 Lizard 无锁全量备份能力。
Lizard 无锁全量备份架构
Lizard 无锁全量备份引入了一个新的重要组件 Transaction Slot,其作为一个持久化结构,用于记录数据库的变化,其架构图如下:
Transaction Slot 组件
Transaction Slot 作为一个持久化的结构,记录了数据库的事务型变化,其包括:
1.事务状态
通过 state 字段,记录事务的状态,包括active,prepare,commit,rollback等状态,在恢复过程中,通过 state 字段,所有 active 或者 prepare 状态的 transaction 都统一进行 rollback。
2.事务提交版本
通过 SCN 字段,记录事务提交或者回滚的内部版本号,即 System Commit Number。
3.事务全局标记
通过 GTID 字段,记录事务提交或者回滚的唯一标识,即 Global Transaction Identifier 。为了保证记录的完整性,对于数据库的所有变化包括:
- 数据操作语言(DML)
- 数据定义语言(DDL)
- 数据控制语言(DCL)
都强制分配了 Tranaction Slot,以便记录所有的 GTID,从而保证实例恢复后,应用 Binlog 的幂等性。
Lizard 一致性恢复
通过 Transaction Slot 组件, PolarDB-X 存储引擎 DN 节点不再通过 global lock 获取位点,实现了无锁全量备份,而针对全量备份集进行 recovery 过程中,需要处理的三个核心位点,即: Recovery 恢复位点,Consensus 传输位点,Apply 应用位点,无锁全量备份进行了松散处理,并保证了最终一致性。
1.Recovery 恢复位点
物理恢复的位点,按照物理备份中 redo log copy 到的最后日志位置,作为恢复的最终位置,备份过程,copy了从checkpoint 位置之后的所有 redo log,在恢复的时候,重新应用这些 redo log,并回滚所有active/prepare状态的事务。
2.Consensus 传输位点
由于 DN 节点采用 X-Paxos 一致性协议, 其核心是在提交过程中,进行多数派达成,所以在备份结束之前,获取一个多数派 Binary Log 的位点,作为 Consensus 传输位点,在实例恢复过程中,以 Learner 的角色重新加入集群中,从这个位点开始接收 Binary Log。
3.Apply 应用位点
由于没有 Global Lock 的保护,无法获取 Binary Log 和存储引擎一致的应用位点,所以在备份完成之前,获取了一个已经 Applied 位点,在实例恢复后,apply 过程中,通过 Transaction Slot 构建的 GTID executed 集合,进行幂等控制,最终追上集群的位点。
通过上述位点的获取和应用逻辑,保证了备份集在接入到原始集群后,能够整合协议层、复制层和数据层,最终实现系统各部分之间的严格一致性。