数据库主从节点的数据一致性是保证数据库高可用的基本要求,各个数据库在实现方式上也各有异同。而主备复制的方式无外乎两种:物理复制和逻辑复制,本文简要对比下两种方式的不同,并分析下国产数据库是如何实现的。
1、数据库复制基本概念
数据库主从复制是保证金融级数据库高可用的重要手段,通过在多个数据库节点上保留相同数据的副本,从而确保即使某个节点发生故障,其他节点仍然能提供数据服务,从而提高系统的整体可用性。主备复制的分类有很多种:按照同步方式的复制分为同步、半同步和异步的方式;按照复制方向分为单向复制和双向复制,像数据库迁移这种有时候需要做反向同步;按照复制的实现技术分为存储级别复制和数据库级别复制。本文主要介绍不同数据库主备节点之间的物理复制和逻辑复制实现。
1.1 物理复制
物理复制也称为二进制或流式复制,数据库主库(或源数据库)将数据库的物理文件(如数据文件、日志文件等)或其变化(如二进制日志中的变化)以byte2byte的方式发送给从库(或目标数据库),从库则应用这些文件或变化来保持与主库数据的一致性。物理复制具有以下好处:
- 数据高度一致性:主从节点的数据在物理层面保持一致性,满足金融级的可靠性要求,不用担心数据在逻辑层面的不一致;
- 低时延:事务在执行过程中产生的Redo记录会实时的apply到备库,事务结束后就能看到数据,具备较低的复制时延;
- 复制效率高:物理层面复制数据,能达到较高的复制效率。
以PostgreSQL数据库为例,当用户执行DML或DDL操作后,产生的WAL日志会通过wal sender进程实时发送到备库,备库的wal receiver进程接收后写入本地wal日志,之后startup进程会读取wal日志并应用到备库。
在PostgreSQL9.0之前不支持流式复制,而是等主库写完一个WAL日志文件后,才把WAL日志文件传送到备库,这样的方式导会致主备延迟特别大。9.0版本之后引入了流式复制机制,通过流复制,备库几乎实时的从主库同步相应的WAL记录。
不过基于物理数据块的物理复制也有缺点,有一些使用上的限制和无法覆盖的场景:
- 数据页损坏:物理复制直接复制数据文件,如果复制过程中发生文件读写错误或磁盘损坏等问题,可能会导致数据损坏。
- 只支持实例级别的复制,无法进行表级别或逻辑对象的过滤,比如某类DDL操作不想复制到备库
- 主从库间版本兼容性:主从库在不同版本和不同操作系统之间进行复制可能存在兼容性问题,在版本升级或操作系统升级时候尤其需要关注
1.2 逻辑复制
逻辑复制是基于SQL层的数据复制技术,通过解析和复制数据库中的逻辑变化(如INSERT、UPDATE、DELETE等SQL语句)来实现数据同步。逻辑复制有以下特性:
- 灵活度高:可以选择性的复制特定的表或数据操作,不需要整个数据库实例;
- 异构数据库同步:由于逻辑复制是基于SQL层的操作,因此可以实现不同数据库实例之间的数据同步,甚至可以在不同数据库系统之间同步数据。
- 可能存在延迟:由于需要解析和转换SQL语句,受限于备机性能或大事务语句可能存在一定的复制延迟
以MySQL数据库为例,当主库上有提交或数据更改时(如INSERT、UPDATE、DELETE),这些变更操作会被记录到二进制日志binlog中。从库上有一个I/O线程,它负责连接主库并从主库的二进制日志中读取数据。这些数据在从库上会被写入中继日志(Relay Log),中继日志是从库上的二进制日志的副本。从库上的SQL线程会读取中继日志中的事件,并将这些事件逐条应用到从库数据库上,从而使从库的数据与主库保持一致。
逻辑复制由于网络IO问题、大事务或者备机性能差及高并发等场景可能会导致relay log无法及时的写入备机,从而出现主从节点之间复制延迟过大。通常在主库高并发的场景下可以保证binlog日志已经传到备机,也就是RPO=0。
1.3 物理复制和逻辑复制特性对比
数据库主从节点间的复制方式是由各数据库自身的能力决定的,比如PostgreSQL数据库原生的支持物理复制,而不会选用更为复杂的逻辑复制实现;MySQL原生的使用逻辑复制实现。像PostgreSQL如果要实现跨数据库之间的数据同步,就需要将WAL日志解析为逻辑上的事务流,再同步到目标数据库中。物理复制和逻辑复制之间的特性对比如下:
- 数据一致性:物理复制是基于物理层面数据块的复制,可以确保数据的高一致性;逻辑复制则是基于SQL语句的复制,可能出现数据不一致,比如主键冲突、数据丢失等,当出现主备机数据不一致时需要通过修复备机的方式应急。
- 数据复制效率:物理复制直接复制数据文件来同步数据,相比逻辑复制执行大量SQL语句的方式,其速度更快。
- 数据文件完整性:物理复制在数据文件传输过程中可能可能会出现数据损坏的情况,备机无法读取文件的时候也需要修复备机或者重传文件修复。
- 兼容性问题:当主备库版本不同或者操作系统版本不同,可能存在兼容性问题,逻辑复制是基于SQL重做的,不会存在兼容性问题。
- 数据复制灵活性:逻辑复制允许自定义复制过程中使用的SQL语句,因此可以实现更灵活的数据复制策略,比如不需要复制哪一类表或语句。
- 数据复制延迟:逻辑复制主备节点间的复制延迟影响因素较多,比如住备库之间的网络IO、备库的性能、主库高并发事务写入等,可能会存在一定的复制延迟;物理复制主要受限于主备节点之间的网络和备节点的性能情况。
除了以上还有其他一些限制,比如PostgreSQL逻辑复制中不能同步DDL、Sequence和大对象不能复制,物理复制中备机只读、备机逻辑复制中和备份会出现冲突等情况。
2、国产数据库复制类型对比
2.1 MySQL系的数据库
国产数据库中MySQL系数据库指的是数据库存储引擎是兼容MySQL的,比如GoldenDB、TDSQL for MySQL,这一类数据库的主从节点复制方式是逻辑复制的,基于binlog日志的同步和解析实现备机的数据同步。
2.2 PostgreSQL系的数据库
国产数据库中PostgreSQL系的数据库如openGauss、GaussDB(for opengauss)等,主从节点的复制方式是集成了PG数据库原生的能力,基于WAL日志的物理复制方式实现的。
2.3 OceanBase数据库
OceanBase是基于Paxos协议的多副本复制架构,通过数据分区复制、日志同步等方式将数据同步到多个副本之上。OB中通过RedoLog来保证事务性,事务提交时利用Paxos协议在多个节点间同步RedoLog达成多数派提交,从而维护副本间数据的一致性。首先分区的所有副本(包括主副本自身)会在日志落盘成功后发起投票。当多数派副本都表决日志落盘成功后,业务事务在主副本提交返回。而备副本在接收到主副本同步过来的日志后,会按照日志中的操作指令进行数据的重放。Paxos协议保证了即使主副本发生故障,备副本也能够从多数派副本中找到完整的日志记录,并应用在新的主副本上,从而确保数据的高可用性和一致性。因此可以看到OceanBase数据库主备复制之间的数据同步是物理复制的方式实现的。
2.4 TiDB数据库
TIDB是基于Raft协议保证多副本数据一致性,每个Region会有多个副本,其中一个副本是leader,任何写请求都只能在 Leader 上写入,并且需要写入多数副本后才会返回客户端写入成功。
- Leader将写操作写入其日志(Region Raft Log),并并行地将该操作发送给所有Follower副本。
- Follower副本将写操作写入自己的日志,并向Leader发送确认。
- 当Leader收到足够数量的确认(通常是大多数副本)后,它将操作应用到其状态机,并向客户端发送成功响应。
- Leader随后通知所有Follower副本应用该操作到它们的状态机。
因此TIDB同一个Region的副本之间的同步方式是物理复制实现的。另外在跨Region的高可用架构中,使用TiCDC实现跨集群的高可用。TiCDC通过拉取上游TiKV的数据变更日志,将数据解析为有序的行级变更数据输出到下游。TiCDC实时监听上游TiKV各个Region Raft Log的信息,并根据每个事务前后数据的差异生成对应多条SQL语句的数据变更信息。TiCDC只保证输出的变更事件和上游TiDB的变更是等价的,不保证能准确还原上游TiDB引起数据变更的SQL语句。
基于TiCDC的数据复制是逻辑复制,在使用上还有一些限制,比如不支持创建Sequence的DDL操作、同步过程中不支持对同步的表或库的恢复或导入操作等。
2.5 达梦数据库
达梦数据库的主备实例由主库、备库、守护进程和监视器组成,DM数据守护将主库产生的Redo日志传输到备库,备库接收并重新应用Redo日志,从而实现备库与主库的数据同步。其核心思想是监控数据库状态,获取主、备库数据同步情况,为Redo日志传输与repay过程中出现的各种异常情况提供一系列的解决方案。可以看到主备间是物理复制的方式。
达梦数据库的主备同步方式分为实时主备模式(高性能模式)和即时主备模式(高可靠模式)
- 在实时主备模式下,数据同步的实时性较高,但更注重性能表现。这种模式下,主库在将Redo日志(RLOG_PKG)写入联机日志文件之前,会先将Redo日志发送到备库。备库在收到Redo日志后,会将其标记为KEEP_PKG,并立即将原KEEP_PKG加入日志重演任务系统,同时马上响应主库,而不需要等待Redo日志重演结束。主库在收到备库的响应消息,确认备库已经收到Redo日志后,再将Redo日志写入联机日志文件中。
- 即时主备模式则更注重数据的一致性和完整性。在这种模式下,主库先将Redo日志写入联机日志文件,然后通过MAL系统(可能是指达梦特有的消息传递和日志系统)将Redo日志发送到备库。备库在收到Redo日志后,会进行即时归档,并在重演完Redo日志后响应主库。这种模式的同步机制可以保证备库的Redo日志不会比主库的Redo日志多,从而确保数据在事务层面的一致性。
2.6 总结
本文简要介绍了不同数据库主备副本之间的物理复制和逻辑复制方式,各类数据库在底层引擎构建设计时多有不同,比如MySQL系的数据库以逻辑复制为主,而PostgreSQL系或其它分布式数据库类似Oracle数据库的物理复制。两种方式不是非此即彼的关系,各自都有些优缺点和适用场景。不管使用何种实现方式,最终目的是要能够保证主备节点之间数据的一致性,满足高复制性能、低复制时延的基本要求。
数据库 | 类型 | 集群内主备同步 | 跨集群 |
---|---|---|---|
达梦数据库 | 集中式 | 物理复制 | |
OceanBase | 分布式 | 物理复制 | 物理复制 |
GoldenDB | 分布式 | 逻辑复制 | 逻辑复制 |
TDSQL(for MySQL) | 分布式 | 逻辑复制 | 逻辑复制 |
OpenGauss | 集中式 | 物理复制 | 物理复制 |
GaussDB(for opengauss) | 分布式 | 物理复制 | 物理复制 |
TiDB | 分布式 | 物理复制 | 逻辑复制 |
参考资料:
- https://www.modb.pro/db/52463
- https://blog.csdn.net/Laugh_xiaoao/article/details/127033658
- https://docs.pingcap.com/zh/tidb/stable/ticdc-overview