PostgreSQL 9.1.2总控walsender.c源码分析


一、程序涉及到的一些知识

1、主服务器是以连续的归档模式操作的,而备用服务器是以连续的恢复模式从主服务器的WAL文件中读取数据。

2、归档进程pgarch就是负责在重做日志文件切换后将已经写满的重做日志文件复制到归档日志文件中,以防止循环写入重做日志文件时将其覆盖。所以说,只有数据库运行在归档模式时,这个pgarch进程才会被启动。

3、日志传送是异步进行的。WAL记录的传送是在事务提交之后进行的。

4、辅助服务器可以通过TCP连接(所谓的流复制)从WAL归档或者主服务器的目录中读取WAL记录。

5、如果想用流复制,必须在主服务器中设置相应的权限,以使来自备用服务器的流复制连接得到许可。这个需要在pg_hba.conf文件中做相应的配置。本代码中的max_wal_senders变量也是在这个文件做配置的,以提供足够大的值来存储备用服务器的数量。

二、walsender.c主要函数功能详解

walsender.c程序中的函数都是为walsender进程发送WAL记录而准备的,包括了walsender进程的入口函数、初始化函数、读取WAL记录的XlogRead函数、XlogSend函数以及walsender进程处理相关的信号函数等。

1、walsender进程重要的数据结构

(1)、标记walsender进程的状态枚举

在walsender进程的生命周期中,进程存在四个状态,即:启动状态、备份状态、获取异常状态以及终止状态。其定义如下所示: 

[cpp]
  1. typedef enum WalSndState  
  2.   
  3. {  
  4.   
  5.     WALSNDSTATE_STARTUP = 0,         /*启动状态*/  
  6.   
  7.     WALSNDSTATE_BACKUP,                 /*备份状态*/  
  8.   
  9.     WALSNDSTATE_CATCHUP,             /*获取异常状态*/  
  10.   
  11.     WALSNDSTATE_STREAMING               /*关闭状态*/  
  12.   
  13. } WalSndState;  

下面就walsender进程的四个状态以及何时处于一种特定的状态进行说明:

①、在刚刚创建的时候是处在启动状态;

②、在日志的发送过程中,一直都是处在备份的状态;

③、如果walsender进程在休眠的时候接收到一些异常信号的时,walsender进程的状态标记为catchup态,标记出进程在和 walreceiver通信的过程中出现一些不可以处理的异常,比如:walreceiver进程请求的文件不存在、walsender进程和walreceiver进程的通信链接断开等等。

④、walsender进程在休眠的时候接收到一些异常信号的时候,会由catchup态转换为终止态,在这个状态的时候,进程一般需要处理相关的异常处理,比如发送出一些留在缓冲区中尚未发送出去的WAL日志文件、进程退出等。

(2)、存储每一个walsender进程的信息数据结构

在postgreSQL数据库系统中,可能存在多个walsender进程用来为walreceiver进程发送请求的WAL记录,如果不对每个walsender进程加以标记,整个系统将会很混乱,这个用来存储walsender进程信息的数据结构定义在src\include\replication\walsender.h文件中。其结构如下所示:

[cpp]
  1. typedef struct WalSnd  
  2.   
  3. {  
  4.   
  5.     pid_t      pid;           /* walsender进程的ID*/  
  6.   
  7.     WalSndState state    /* walsender的状态*/  
  8.   
  9.     XLogRecPtr sentPtr;   /* WAL发送点*/  
  10.   
  11.     XLogRecPtr write;     /*写的位置*/  
  12.   
  13.     XLogRecPtr flush;     /*刷新的位置*/  
  14.   
  15.     XLogRecPtr apply;     /*被应用的位置*/  
  16.   
  17.     slock_t    mutex;        //互斥信号量,保护上面的共享变量      
  18.   
  19. Latch      latch;   
  20.   
  21.     int    sync_standby_priority;  
  22.   
  23. } WalSnd;  

在WalSnd结构体中,定义了存储walsender进程的ID号,在系统中每一个进程的ID号是不一样的,这样用进程号来标记共享内存中的WalSnd结构,将会带来很大的方便。在WalSnd结构体中定义的内容分别简述如下:

①、pid:存储walsender进程的ID号;

②、state:存储walsender进程的状态,其状态含义在上面陈述过;

③、write、flush以及apply:分别记录辅助服务器中xlog被写、刷新和应用的位置,如果辅助服务器还没有为它们赋值,则它们是无效的;

④、mutex:互斥信号量,是int类型的,用来控制一些临界资源,使得临界资源一次只能被一个进程所读、写等操作;

⑤、latch:用来保护③中的三个变量,其作用相当于一把锁;

⑥、sync_standby_priority:辅助服务器的优先级顺序,为0则表示没有被排列,被同步复制锁SyncRepLock保护。

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 下一页

相关内容