PostgreSQL 主备流复制启动过程

我们知道, 在PostgreSQL流复制过程中,有三个进程协同工作:walsender进程,walreceiver进程和startup进程。其中walsender进程属于主节点的进程,主要用来向备节点发送wal record; walreceiver和startup进程属于备节点进程,wal receiver主要用来接收主端发送来的wal record,之后startup进程就会对这些wal数据进行replay。三个进程共同协作,完成主备的整个流复制过程。

在流复制过程中,三个进程的WAL DATA的执行顺序是:

            walsender ---> walreceiver ---> startup

但在流复制启动过程中,三个进程的启动顺序正好是反过来的,即:

            startup ---> walreceiver ---> walsender

 

下面我们就介绍下三个进程是怎么启动的以及启动过程中都需要哪些条件。

流复制启动过程中,首先启动的startup进程, 然后触发启动wal receiver进程,之后wal receiver发送信号,启动wal sender进程。

下图是三个进程启动过程示意图:

 

1.Startup进程启动条件很简单,在流复制场景中,只要数据库实例进入standby模式(即在recovery.conf中配置standby_mode=on), startup就会随着数据库服务启动。

2. Startup启动后,不会马上发送信号给postmaster来启动wal receiver进程,它先会进行一系列条件的判断然后决定是否通知postmaster启动wal receiver进程。 首先它会检查接下来要replay的wal是否本地已经存在,还是需要从primary节点发送过来。只有当需要从primary节点发送wal时, 才会触发startup发送信号给postmaster请求创建wal receiver进程。

在startup进行replay的过程中,WAL文件的读取顺序在内核中是通过以下宏定义的:

typedef enum
{
XLOG_FROM_ANY = 0, /* request to read WAL from any source */
XLOG_FROM_ARCHIVE, /* restored using restore_command */
XLOG_FROM_PG_WAL, /* existing file in pg_wal */
XLOG_FROM_STREAM /* streamed from master */
} XLogSource;

即系统在恢复过程中,获取WAL Segment是按照以下顺序执行:

         1. 先从归档中获取

         2. 然后再从pg_wal中获取

         3. 最后需要从primary 节点以流复制方式获取

所以在实际流复制过程中, 如果是非归档,则从会pg_wal中获取;否则优先从archive归档中获取(Archive Mode); 如果两者都没有startup要恢复的wal,则startup会发送信号(通过函数SendPostmasterSignal(PMSIGNAL_START_WALRECEIVER) )给postmaster进程,请求其需要启动wal receiver进程以便从Primary节点来获取wal数据。

Tips: 下面就可以解释:为什么在备库启动时,有时候wal receiver进程不能立即启动

这是因为pg_wal或archive归档目录中,还有未恢复的WAL Segment,而系统即使在streaming模式,也会优先从这两个目录进行恢
复; 如果pg_wal或archive归档目录都没有,则才开始从primary节点以流复制方式获取,startup进程给postmaster进程发送信
号,准备启动wal receiver进程。实际上只要本地有没有replay完的WAL,获取wal的数据源就不会跳到XLOG_FROM_STREAM这个模
式中。 

其次,决定是否发通知还需要判断是否配置了primary_conninfo参数。因为这是需要和primary建立连接的必要信息。

上述条件满足后,startup开始向primary发送SendPostmasterSignal(PMSIGNAL_START_WALRECEIVER),请求postmaster创建wal receiver进程, 在该过程中,还会有以下条件的判断,然后决定是否创建wal receiver进程。

  1. 加载libpqwalreceiver库
  2. 判断备库的system identifier是否和主库一致,即主备是否属于同一个replication cluster。 该过程是standby端向primary发送流复制命令IDENTIFY_SYSTEM,primary端接收到该命令后,会把一串信息(包括system identifier, timeline ID, 当前wal flush location以及database name )反馈给standby。
  3. 判断primary端的timeline是否大于或等于standby端的timeline, 即正常的流复制过程中,要确保primary的timeline要超前standby端的。
  4. 发送TIMELINE_HISTORY命令, 从primary节点抽取wal history文件,以便获取所有的primary timeline信息。
Tips: 
  流复制过程中,主备之间的通信是遵守流复制协议进行的。这其中就包括一系列的Replication Command。 

IDENTIFY_SYSTEM 
         请求服务器(primary)发送系统信息(system identifier, timeline id,wal flush location, dbname)

TIMELINE_HISTORY 
        请求服务器(primary)发送wal history文件过来 

CREATE_REPLICATION_SLOT 
        指示服务器(primary)创建复制槽 

START_REPLICATION 
        请求服务器(primary)启动replication 

BASE_BACKUP 
        指示服务器(primary)开始传送一个基础备份

当然还有其他流复制命令,这里不一一列举了,具体可参考手册<流复制协议章节>

 

满足上述条件后,启动wal receiver进程。Walreceiver进程启动后, 会向primary postmaster端发送包含receiver信息的startup packet, primary端的postmaster读取该packet,并按照信息启动wal sender进程, 并建立和wal receiver一条TCP连接。至此,整个流复制的启动过程创建完成,下面就可以进行正常流复制了。

转载于:https://my.oschina.net/tianbing/blog/3007651

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值