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

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


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

初始化walsender和walreceiver相关结构方法调用流程图

 

2初始化xlog相关结构

        话说main()->…->PostmasterMain()->…->reset_shared() ->CreateSharedMemoryAndSemaphores()>…->WalSndShmemInit(),调用ShmemInitStruct(),在其中调用hash_search()在哈希表索引"ShmemIndex"中查找"Wal Sender Ctl",如果没有,就在shmemIndex中给"Wal Sender Ctl"分一个HashElement和ShmemIndexEnt(entry),在其中的Entry中写上"WalSender Ctl"。返回ShmemInitStruct(),再调用ShmemAlloc()在共享内存上给"WalSender 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"分一个HashElement和ShmemIndexEnt(entry),在其中的Entry中写上"WalReceiver Ctl"。返回ShmemInitStruct(),再调用ShmemAlloc()在共享内存上给"WalReceiver 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 structin 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 xloglocations that have been written, flushed, and applied by

     * standby-side. These maybe 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 backendsto wake up this walsender when it has work to

     * do.

     */

    Latch      latch;

 

    /*

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

     * insynchronous_standby_names, or 0 if not-listed. Protected by

     * SyncRepLock.

     */

    int        sync_standby_priority;

} WalSnd;

 

extern WalSnd *MyWalSnd;

 

/* There is one WalSndCtl structfor the whole database cluster */

typedef struct

{

    /*

     * Synchronous replicationqueue. Protected by SyncRepLock.

     */

    SHM_QUEUE  SyncRepQueue;

 

    /*

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

     * waitLSN that followsthis value. Protected by SyncRepLock.

     */

    XLogRecPtr lsn;

 

    /*

     * Are any sync standbysdefined?  Waiting backends can'treload the

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

     * Protected bySyncRepLock.

     */

    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 formanagement of walreceiver process */

typedef struct

{

    /*

     * PID of currently active walreceiverprocess, 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 thefirst byte position that will be received. When

     * startup process startsthe walreceiver, it sets receiveStart to the

     * point where it wants thestreaming to begin.

     */

    XLogRecPtr receiveStart;

 

    /*

     * receivedUpto-1 is thelast byte position that has already been

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

     * receiveStart. Afterthat, walreceiver updates this whenever it flushes

     * the received WAL todisk.

     */

    XLogRecPtr receivedUpto;

 

    /*

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

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

     * receivedUpto before thelast flush to disk.   Startup process canuse

     * this to detect whetherit's keeping up or not.

     */

    XLogRecPtr latestChunkStart;

 

    /*

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

     */

    char       conninfo[MAXCONNINFO];

 

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

} WalRcvData;

 

extern WalRcvData *WalRcv;

 

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

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

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

 

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

 Wal Sender CtlWal Receiver Ctl相关结构图


你可能感兴趣的:(struct,database,search,PostgreSQL,byte,variables)