PostgreSQL启动过程中的那些事七:初始化共享内存和信号十八:shmem中初始化WalSender和WalRecv相关结构...

1 先上个图,看一下函数调用过程梗概,中间略过部分细节


初始化 walsenderwalreceiver 相关结构 方法调用流程图

 

2 初始化 xlog 相关结构

话说 main()->->PostmasterMain()->->reset_shared() -> CreateSharedMemoryAndSemaphores()>->WalSndShmemInit() ,调用 ShmemInitStruct() , 在其中 调用 hash_search() 在哈希表索引 "ShmemIndex" 中查找 "Wal Sender Ctl" ,如果没有,就在 shmemIndex 中给 "Wal Sender Ctl" 分一个 HashElementShmemIndexEntentry ) ,在其中的 Entry 中写上 "Wal Sender Ctl" 。返回 ShmemInitStruct() ,再调用 ShmemAlloc() 在共享内存上给 "Wal Sender Ctl" 相关结构(见下面“ Wal Sender CtlWal Receiver Ctl 相关结构图” )分配空间,设置 entry (在这儿及ShmemIndexEnt 类型变量)的成员 location 指向该空间, size 成员记录该空间大小 , 最后返回 WalSndShmemInit () ,让 WalSndCtlData * 类型 全局变量 WalSndCtl 指向 所分配内存 ,初始化WalSndCtlData 结构类型的成员值。

接着 WalRcvShmemInit() -> ShmemInitStruct() , 在其中 调用 hash_search() 在哈希表索引 "ShmemIndex" 中查找 "Wal Receiver Ctl" ,如果没有,就在 shmemIndex 中给 "Wal Receiver Ctl" 分一个 HashElementShmemIndexEntentry ) ,在其中的 Entry 中写上 "Wal Receiver Ctl" 。返回 ShmemInitStruct() ,再调用 ShmemAlloc() 在共享内存上给 "Wal Receiver Ctl" 相关结构(见下面“ Wal Sender CtlWal Receiver Ctl 相关结构图” )分配空间,设置 entry (在这儿及ShmemIndexEnt 类型变量)的成员 location 指向该空间, size 成员记录该空间大小 , 最后返回 WalRcvShmemInit () ,让 WalRcvData * 类型 全局变量 WalRcv 指向 所分配内存 ,初始化WalRcvData 结构类型的成员值。

 

相关结构定义和图见下面:

typedef enum WalSndState

{

    WALSNDSTATE_STARTUP = 0,

    WALSNDSTATE_BACKUP ,

    WALSNDSTATE_CATCHUP ,

    WALSNDSTATE_STREAMING

} WalSndState ;

 

/*

  * Each walsender has a WalSnd struct in shared memory.

  */

typedef struct WalSnd

{

    pid_t       pid ;          /* this walsender's process id, or 0 */

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

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

 

    /*

      * 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 ;

 

    /* Protects shared variables shown above. */

    slock_t        mutex ;

 

    /*

      * Latch used by backends to wake up this walsender when it has work to

      * do.

      */

    Latch       latch ;

 

    /*

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

      * in synchronous_standby_names, or 0 if not-listed. Protected by

      * SyncRepLock.

      */

    int         sync_standby_priority ;

} WalSnd ;

 

extern WalSnd *MyWalSnd;

 

/* There is one WalSndCtl struct for the whole database cluster */

typedef struct

{

    /*

      * Synchronous replication queue. Protected by SyncRepLock.

      */

    SHM_QUEUE   SyncRepQueue ;

 

    /*

      * Current location of the head of the queue. All waiters should have a

      * waitLSN that follows this value. Protected by SyncRepLock.

      */

    XLogRecPtr lsn ;

 

    /*

      * Are any sync standbys defined?  Waiting backends can't reload the

      * config file safely, so WAL writer updates this value as needed.

      * Protected by SyncRepLock.

      */

    bool        sync_standbys_defined ;

 

    WalSnd      walsnds [1];       /* VARIABLE LENGTH ARRAY */

} WalSndCtlData ;

 

extern WalSndCtlData *WalSndCtl;

 

typedef enum

{

    WALRCV_STOPPED ,             /* stopped and mustn't start up again */

    WALRCV_STARTING ,         /* launched, but the process hasn't

                              * initialized yet */

    WALRCV_RUNNING ,             /* walreceiver is running */

    WALRCV_STOPPING              /* requested to stop, but still running */

} WalRcvState ;

 

/* Shared memory area for management of walreceiver process */

typedef struct

{

    /*

      * PID of currently active walreceiver process, its current state and

      * start time (actually, the time at which it was requested to be

      * started).

      */

    pid_t       pid ;

    WalRcvState walRcvState ;

    pg_time_t   startTime ;

 

    /*

      * receiveStart is the first byte position that will be received. When

      * startup process starts the walreceiver , it sets receiveStart to the

      * point where it wants the streaming to begin.

      */

    XLogRecPtr receiveStart ;

 

    /*

      * receivedUpto-1 is the last byte position that has already been

      * received.  At the first startup of walreceiver , receivedUpto is set to

      * receiveStart. After that, walreceiver updates this whenever it flushes

      * the received WAL to disk.

      */

    XLogRecPtr receivedUpto ;

 

    /*

      * latestChunkStart is the starting byte position of the current "batch"

      * of received WAL.  It's actually the same as the previous value of

      * receivedUpto before the last flush to disk.   Startup process can use

      * this to detect whether it's keeping up or not.

      */

    XLogRecPtr latestChunkStart ;

 

    /*

      * connection string; is used for walreceiver to connect with the primary.

      */

    char        conninfo [MAXCONNINFO];

 

    slock_t        mutex ;        /* locks shared variables shown above */

} WalRcvData ;

 

extern WalRcvData *WalRcv;

 

初始化完 Wal Receiver CtlWal Receiver Ctl 相关结构 的共享内存结构图

       为了精简上图,把创建 shmem 的哈希表索引 "ShmemIndex" 时创建的 HCTL 结构删掉了,这个结构的作用是记录创建可扩展哈希表的相关信息,不过这个结构在 "ShmemIndex" 创建完成后也会由于出了对象作用域而消失。增加了左边灰色底的部分,描述 共享内存 /shmem 里各变量物理布局概览,由下往上,由低地址到高地址。 图中黄色的索引项就是本节新增加的索引项。

 

 

Wal Sender CtlWal Receiver Ctl 相关结构图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值