postgresql walsender源码分析

 


目录

前言

介绍

数据结构

WAL对端的状态

walsender进程

WALsender交互流程

在握手阶段,主要做了两件事情:

在握手交互后,开始真正开始wal传送,调用关系如下:

walsend进程流程

结尾


前言

本文是基于postgresql 15的代码进行分析解读,演示是在centos8系统上进行。


介绍

walsender 看名字就知道,它是通过tcp协议发送write ahead log。

那么它是什么场景下使用呢?

以及如何获得wal产生的呢?

如何与对应协调呢?

下面我们就来看看。

数据结构

typedef struct WalSnd

{

pid_t                pid;                        /* this walsender's PID, or 0 if not active */



WalSndState state;                        /* this walsender's state */

XLogRecPtr        sentPtr;                /* WAL has been sent up to this point */

bool                needreload;                /* does currently-open file need to be

 * reloaded? */



/*

 * The xlog locations that have been written, flushed, and applied by

 * standby-side. These may be invalid if the standby-side has not offered

 * values yet.

 */

XLogRecPtr        write;

XLogRecPtr        flush;

XLogRecPtr        apply;



/* Measured lag times, or -1 for unknown/none. */

TimeOffset        writeLag;

TimeOffset        flushLag;

TimeOffset        applyLag;



/*

 * The priority order of the standby managed by this WALSender, as listed

 * in synchronous_standby_names, or 0 if not-listed.

 */

int                        sync_standby_priority;



/* Protects shared variables in this structure. */

slock_t                mutex;



/*

 * Pointer to the walsender's latch. Used by backends to wake up this

 * walsender when it has work to do. NULL if the walsender isn't active.

 */

Latch           *latch;



/*

 * Timestamp of the last message received from standby.

 */

TimestampTz replyTime;



ReplicationKind kind;

} WalSnd;

这是walsender上下文的记录,记录了walsender进程pid, 以及wal发送的记录位置等。

WAL对端的状态

WAL记录,有三种状态,记录了接收端的WAL处理情况;

writed, WAL已经接收被写入磁盘;

flush, WAL被刷到磁盘上;因为先是写到缓存中,接收一部分后统计调用flush。

apply, WAL日已经在备机被回放应用了;

walsender进程

启动方式与backend一样,在postmaster收到replication的连接后启动一个backend,这个backend不处理SQL,只处理replication相关的命令。

其中对于physicalreplication,也就是流复制,主要就是发送wal。几种场景下都会启动walsender,一是在pg_basebackup时,通过walsender发送数据拷贝和wal;二是在热备时,主节点向备节点发送wal;三是级联的备节点时,上级备节点向下级备节点wal;

WALsender交互流程

在walsender启动之后,walsender与walreceiver需要进行握手交互,交互流程如下:

(1)备->walsender  "IDENTIFY_SYSTEM"

walsender->备 回复

(2)备->walsender "START_REPLICATION 6/4A000000 TIMELINE 3" 

T_StartReplicationCmd

(3)walsender查找 historytimeline找到对应的切换lsn,如果请求的startlsn还在,就按请求的位置发送;

  • 在握手阶段,主要做了两件事情:

(1)确认主机版本;

(2)协商WAL发送的起始位置;备机请求的lsn,在主机上是否存在,如果是过期的,WAL已经不存在了或者还没产生,那就流复制失败;

  • 在握手交互后,开始真正开始wal传送,调用关系如下:

exec_replication_command

->IdentifySystem

->StartReplication

->WalSndLoop

  • walsend进程流程

walsender在流复制过程中,一直会在WalSndLoop循环,大概流程如下:

(1)发送WAL调用XLogSendPhysical,从wal文件里直接读取数据;

每次最大可以发送16倍的xlog block;

#define MAX_SEND_SIZE (XLOG_BLCKSZ * 16)

当然这个大小可以与walreceiver进行协商,来控制流量;

(2)当前没有可发的WAL时,调用WalSndWait进行等待;如果网络阻塞也会在此等待事件;

(3)空闲时会发送keepalive消息;

(4)事件等待,在XlogWrite时通过WalSndWakeupRequest()打开walsender通知开关,说明已经有WAL写入磁盘;当有WAL刷盘完成后,在XLogFlush中通过WalSndWakeupProcessRequests通知walsender进行发送;


结尾

作者邮箱:[email protected]
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

猜你喜欢

转载自blog.csdn.net/senllang/article/details/130668326
今日推荐