文档首页/ 云数据库 TaurusDB/ 最佳实践/ TaurusDB主备复制原理解析
更新时间:2026-07-03 GMT+08:00
分享

TaurusDB主备复制原理解析

背景介绍

在数据库架构中,主机(Master)、备机(Replica)以及只读节点(Read Replica)是实现高可用性、负载均衡和数据备份的核心组件。

MySQL的主备使用Share-nothing的架构,通过Binlog实现主备复制。TaurusDB与MySQL的主备架构不同,TaurusDB使用的共享存储架构,主备之间通过Redo日志实现同步,仅需传递少量的元数据信息。备机从共享存储读取Redo日志,通过失效旧的数据页面、回放元数据锁、更新事务快照、缓存日志等处理,实现了主备快速同步。

本章节主要介绍TaurusDB主从复制的实现原理与主要流程。

TaurusDB主备架构

TaurusDB是一种Share-storage的架构,主备之间也不使用Binlog来实现同步。

在MySQL社区中,备机指传统主从复制中的从库。它从主库接收二进制日志并应用,保持数据一致,主要用于故障切换(Failover)和数据冗余。只读节点被专门配置为不接受任何写操作的MySQL实例,通常用来横向扩展读能力,分担主库的读压力。它可以是备机,也可以是级联的从库,甚至是一个独立的不参与高可用切换的节点。

对于TaurusDB,不区分备机和只读节点。

如图所示,TaurusDB使用一种Shared Everything的理念,通过Redo日志来实现主机和只读节点之间的同步,而且主机与只读节点之间不直接传输Redo日志数据,仅同步少量必须的元数据,这部分元数据主要用于从共享存储系统正确的读取数据。

主机写入存储池的只有Redo日志,数据页面的生成及修改由共享存储系统来进行。主机写Redo日志到共享存储系统,只读节点从共享存储系统读取主机写的Redo日志,来实现主备同步。对于数据页面,主机和只读节点都是从共享存储系统来读取。

这种架构的优势在于,新增只读节点不受数据量大小影响,支持快速新增只读节点,且只读节点与主节点之间的时延低、传输的数据带宽占用低;只读节点可以通过快速在线升主来恢复主节点故障。

图1 TaurusDB的主备架构

主备复制流程

  1. 主备通信

    TaurusDB的只读节点通过处理Redo日志来实现主备同步。主备同步是为了主机新增或修改的数据,只读节点能够尽可能快地查询到。由于TaurusDB的主备使用的是Share-storage的架构,Redo日志并不需要从主机来获取,而是从共享存储读取。主备之间传递的仅是一些必须的元数据信息。

    这些主备之间直接同步的元数据信息主要包括以下方面。

    • 主机发送给只读节点:
      1. Redo日志在共享存储系统中的位置、大小等元信息,用于读取Redo日志。
      2. 表空间数据页面和共享存储系统分片的映射关系,用于读取数据页面。
      3. 初始的事务快照信息,用于事务的可见性判断,会通过解析Redo日志来不断更新。
    • 只读节点发送给主机:

      自身不再使用的Redo日志的位点信息(Recycle LSN),主机使用这些数据来确定回收数据的范围,避免将只读节点仍可能使用的历史数据进行回收。

    只读节点会启动一个与主机通信的线程handle_slave_sync,用于从主机接收和向主机发送所需的元数据信息。

  2. 处理Redo日志

    通过主备通信线程,只读节点获取了所需的信息,可以进行对于Redo日志的读取和处理。

    1. 只读节点主备复制后台线程

      为了加快处理Redo日志,只读节点会启动多组后台线程进行流水线式的并行处理,线程数量可配置。

      这些线程包括reader、dispatcher、parser、advancer、impeller等,它们之间通过event来通知唤醒,以协同完成处理。当主备通信线程通过同步信息发现新的Redo日志时,会通知reader线程从共享存储开始读取Redo日志,随后启动一系列处理流程。

      图2 TaurusDB只读节点的主备复制后台线程
      • Log reader线程:等待主备通信线程handle_slave_sync的通知,从共享存储系统读取Redo日志数据。
      • Log dispatcher线程:等待log reader线程的通知,分发日志到各个log parser线程。
      • Log parser线程:等待 log dispatcher 线程的通知,用于解析Redo日志,主要包括两方面的工作:一是将针对具体数据页面的Redo日志按页面 ID 分组整理;二是将其他类型的Redo日志进行解析处理,以供后续使用,例如汇总已提交的事务ID等。
      • Log impeller线程:主要用于处理修改数据页面的Redo日志,将log parser处理后的日志,针对每个不同的页面ID,合并组织到一起;失效缓冲池(Buffer Pool)中的数据页面,并缓存Redo日志到相应的称为Log Directory的目录结构中,用于后续生成新版本的数据页面。
      • Advancer线程:处理其他主备同步动作,主要包括:元数据锁(Metadata Lock,MDL)的处理,避免表的元数据的修改与数据查询产生冲突;事务快照的更新,获取新的活跃事务和已提交的事务,用于事务可见性判断。
    2. 只读节点解析Redo日志

      Redo日志有多种类型,除了直接针对数据页面内容的修改之外,还包含一些其他信息,需要只读节点进行解析、处理,用于和主机保持同步。对于从共享存储系统读入的每一块Redo日志,都会经过下图中的处理过程。

      图3 TaurusDB只读节点解析处理日志

      直接针对数据页面内容的修改所产生的Redo日志,会以页面ID为key汇总至一个hash表中。一方面,该机制用于使Buffer pool中相同ID的页面失效,从而使只读节点获知。对于该页面ID,后续需要使用时应获取新版本的数据页面。另一方面,这些日志会被缓存在全局的Log Directory中,以便只读节点在需要新版本数据页面时,能够基于已在Buffer pool中的旧版本页面,自行回放对应的Redo日志以生成新版本的数据页面。这样可减少从共享存储中读取页面的开销,从而提升性能。

      只读节点还需要从各种类型的Redo日志中,解析、处理如下信息。

      • 已提交事务的ID列表

        通过Redo日志中的已提交的事务ID信息,可以更新活跃事务列表,用于可见性判断。例如对于可重复度隔离级别,已提交的事务,其修改是可见的,而ID值处于这些已提交事务之间的,Redo日志中没有记录其已提交,属于活跃事务,其修改不可见。

      • 事务Purge No

        用于获取最大的事务ID,以及只读节点事务快照的low limit no的确定。

      • 更新和删除的表空间的信息

        用于更新space cache,如已删除或大小发生扩展。

      • 元数据锁(MDL)相关请求

        Redo日志中记录了DDL语句对于MDL锁的申请和释放等,只读节点模拟同样的申请和释放流程,避免元数据的修改和查询之间产生冲突。例如正在使用的索引,发生了删除。

      • 需要失效的内存对象,如Query Cache等
      • 需要失效的Undo表空间信息

        用于处理主机执行的undo truncate等操作。

      • 需要更新的统计信息

      通过以上处理,只读节点完成对主机的同步,可对外提供基于最新数据的查询服务。但是TaurusDB并不是强一致性的,从原理上来讲,只读节点和主机之间是存在一定时延的。在上述介绍的Redo处理流程,当前这一轮完成前,只读节点只能提供截止到上一次同步完成的Redo日志的位点(Log sequence number, LSN)的数据查询。

相关文档