PostgreSQL启动过程中的那些事七:初始化共享内存和信号十八:sh
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 Ctl和Wal 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 Ctl和Wal 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;
初始化完Wal Receiver Ctl和Wal Receiver Ctl相关结构的共享内存结构图 为了精简上图,把创建shmem的哈希表索引"ShmemIndex"时创建的HCTL结构删掉了,这个结构的作用是记录创建可扩展哈希表的相关信息,不过这个结构在"ShmemIndex"创建完成后也会由于出了对象作用域而消失。增加了左边灰色底的部分,描述共享内存/shmem里各变量物理布局概览,由下往上,由低地址到高地址。图中黄色的索引项就是本节新增加的索引项。
Wal Sender Ctl和Wal Receiver Ctl相关结构图 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |