openGauss——主备同步机制概述

一、WalSender、WalReciver、Startup线程概述:

在PostgreSQL流复制过程中,有三个进程协同工作:walsender进程、walreceiver进程和startup进程。walsender进程位于主节点,负责向备节点发送WAL记录;walreceiver和startup进程位于备节点,walreceiver用于接收主节点发送的WAL记录并写入磁盘上的XLOG文件,随后startup进程对这些WAL数据进行重放。三个进程共同协作,完成主备节点的整个流复制过程。

walsender 负责将 WAL 记录从主服务器发送到 standby 服务器。当主服务器生成新的 WAL 记录时,walsender 会将其发送到 standby 服务器。如果 standby 服务器需要某个 WAL 记录,但本地没有,它可以请求主服务器发送相应的记录。

walreceiver 则负责在 standby 服务器上接收来自主服务器的 WAL 记录,并将其写入本地 WAL 日志文件。一旦记录被写入本地日志,standby 服务器上的其他进程就可以读取并应用这些变更。如果 walreceiver 在等待 WAL 记录时没有收到数据,它可以向主服务器发出请求以获取所需的记录,这通常是通过 walsender 实现的。因此,walsender 和 walreceiver 一起工作,实现了主服务器和 standby 服务器之间的实时数据复制,从而确保了高可用性和数据一致性。

其中,大致的调用栈顺序如下:

  • walsender进程用于发送WAL日志记录,执行顺序为:PostgresMain() -> exec_replication_command() -> StartReplication() -> WalSndLoop() -> XLogSendPhysical()
  • walreceiver进程用于接收WAL日志记录,执行顺序为:sigusr1_handler() -> StartWalReceiver() -> AuxiliaryProcessMain() -> WalReceiverMain() -> walrcv_receive()
  • startup进程用于应用日志,执行顺序为:PostmasterMain() -> StartupDataBase() -> - AuxiliaryProcessMain() -> StartupProcessMain() -> StartupXLOG()

在流复制启动过程中,三个进程的启动顺序为:startup -> walreceiver -> walsender。需要注意的是,Startup进程启动后不会立即通知postmaster启动walreceiver进程,而是先进行一系列条件判断,然后决定是否通知postmaster启动walreceiver进程。Startup进程回放日志所需的WAL文件有三个来源:归档中获取、pg_wal文件夹下获取、从主节点以流复制方式获取。在实际流复制过程中,如果未启用归档模式,优先从pg_wal中获取;若启用归档模式,则优先从归档中获取。如果两者都没有,startup进程会请求主节点以流复制方式获取WAL数据,通过SendPostmasterSignal(PMSIGNAL_START_WALRECEIVER)函数通知postmaster启动walreceiver进程。

在流复制运行中,WAL数据的流向为:walsender -> walreceiver -> startup。主库backend执行业务操作产生的XLOG数据会通过上述流程,从主库walsender进程通过网络发送到walreceiver,接收后写入磁盘,最终由备库的startup进程应用这些XLOG数据。

二、流复制信息:

流复制是主、备之间的一种同步模式,备库不断的从主库同步相应的数据,并在备库接受每个WAL 日志,这里的流复制每次传输单位是WAL日志的record。

总体而言,流复制可以分为两种:

  • 同步复制:主机需要等待备机的反馈结果;
  • 异步复制:主机无需等待备机的反馈结果;

上述两种状态在代码层面是通过代码的登记进行设置的,例如synchronous_commit;

  • remote_apply:事务commit或rollback时,等待其redo在primary、以及同步standby(s)已持久化,并且其redo在同步
    standby(s)已apply。
  • on:事务commit或rollback时,等待其redo在primary、以及同步standby(s)已持久化。
  • remote_write:事务commit或rollback时,等待其redo在primary已持久化; 其redo在同步standby(s)已调用write接口(写到 OS, 但是还没有调用持久化接口如fsync)。
  • local:事务commit或rollback时,等待其redo在primary已持久化;
  • off:事务commit或rollback时,等待其redo在primary已写入wal buffer,不需要等待其持久化;

通过上述可以控制主备的备份级别,目前openGauss用的最主流的还是同步备模式;

对于主备之间的流复制通信,可以有以下的流程:

img

  • 主库端后端进程写入和刷新WAL数据:后端进程通过执行函数XLogInsert()和XLogFlush(),将WAL数据写入并刷新到WAL段文件中。
  • 主库端WAL发送器进程发送WAL数据:WAL发送器进程将写入WAL段文件的WAL数据发送到备库的WAL接收器进程。
  • 主库端后端进程等待ACK响应:在发送WAL数据之后,后端进程通过执行内部函数SyncRepWaitForLSN()获取锁存器,并等待备库的ACK响应。
  • 备库端WAL接收器写入WAL数据:WAL接收器进程通过write()系统函数,将接收到的WAL数据写入备库的WAL段,并向主库的WAL发送器返回ACK响应。
  • 备库端WAL接收器刷新WAL数据:WAL接收器进程通过调用fsync()等函数将WAL数据刷新到WAL段中,并向主库的WAL发送器返回另一个ACK响应,同时通知启动进程相关WAL数据已更新。
  • 备库端启动进程重放WAL数据:启动进程重放已写入WAL段的WAL数据。
  • 主库端WAL发送器释放锁存器:主库端的WAL发送器在收到来自WAL接收器的ACK响应后,释放后端进程的锁存器;

在主备流复制中,同时需要复制槽来保证信息的统一性,用于确保主服务器上的WAL(Write-Ahead Logging)日志记录不会被过早删除,从而保证备份服务器能够接收到所有必要的日志记录。本文将详细介绍复制槽的功能、类型、创建和管理方法,以及使用中的注意事项。

复制槽是PostgreSQL中的一个机制,设计用来防止WAL日志记录在所有备份服务器接收到并处理之前被删除。它可以保证备份服务器在重新连接或暂时离线后,能够从主服务器获取所有必要的数据,从而保持数据的一致性。

复制槽的主要分为:

  • 物理复制槽:用于流复制,确保WAL日志记录在物理复制过程中不会被过早删除,主要用于主服务器和备份服务器之间的数据复制。
  • 逻辑复制槽:用于逻辑复制,跟踪特定数据库的变化,并将这些变化发送给备机。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值