`

PostgreSQL启动过程中的那些事十八:bgwriter进程二

阅读更多

 3

       这节主要讨论 bgwriter 进程到了 BackgroundWriterMain ,设置合适的信号处理句柄, 创建一个资源属主以保持对本进程资源的跟踪 创建一个本进程的所有工作都在其内做的内存上下文 "Background Writer" ,创建这个内存上下文是为了本进程在错误恢复期间能重置 context 并且因此避免可能的内存泄漏。 设置错误跳跃点。接着不堵塞信号(当 postmaster 进程 fork 本进程时用 PG_SETMASK(&BlockSig) 堵塞了他们)。然后进入无限循环,检查并处理任何请求或者最近收到的信号。如果请求了检查 点,就根据情况做一个重启点或做一个检查点;如果没请求检查点,就做一个脏缓存写。然后再接着循环。

 

BackgroundWriterMain 方法的调用序列图

 

 

 

BackgroundWriterMain 方法的调用序列图

 

 

4

下面是 BackgroundWriterMain 流程示意图。


 

BackgroundWriterMain 流程示意图

    BackgroundWriterMain 中主要是根据情况看是否有创建检查点请求,如果有,再进一步根据情况判断是要做一个重启点还是要创建一个检查点,根据情况调用 CreateCheckPoint CreateRestartPoint 方法;如果没有请求检查点,调用 BgBuffferSync 方法做脏缓存写。

 

5

       其中 CreateCheckPoint 方法创建检查点的具体情况参见《 PostgreSQL 启动过程中的那些事十六:启动进程二》。创建重启点的 CreateRestartPoint 方法和 创建检查点相似,但被用于 WAL 恢复期间创建一个点,如果重启,恢复可以从这个点继续前滚而不用重放整个恢复日志。

 


 

CreateRestartPoint 流程示意图

    创建重启点主要是为恢复重启保持一个合适的检查点,这个检查点必须是一个安全的重启点。如果可能创建一个重启点,创建重启点主要是把数据库系统共享内存中的数据全部刷出到磁盘,并把可以安全重启的检查点存入控制文件和共享内存中相关变量,详细信息参见上面的“ CreateRestartPoint 流程示意图”。

 

6

BgBuffferSync 方法根据策略调用 SyncOneBuffer 把需要同步的脏缓存块逐个写出。 pg 里缓存池里的所有缓存块是由以 Nbuffers BufferDesc 结构数组里的 freeNext 组成的空闲缓存链表和一个查找缓存的哈西表索引 Shared Buffer Lookup Table ”(参见《 PostgreSQL 启动过程中的那些事七: shmem 中初始化 BufferPool 》)进行管理。其中, SyncOneBuffer() -> FlushBuffer() -> smgrwrite() ,在存储管理器 smgr smgrwrite 方法里根据 smgr 的接口 smgr_write 和规则转到磁盘 md mdwrite 方法。 mdwrite 方法不是同步写——在返回时块不是必须在磁盘上,其只是把这个缓存块的内容传到 OS kernel ,最终调用 OS Write 接口, kernel 再根据情况安排写磁盘任务。但是,在下一次检查点记录到 WAL 日志前通过文件同步 fsync 我们将强制将这些改变的缓存块写到磁盘。

BgBuffferSync 方法里多次提到 clock sweep 算法, clock sweep 算法是缓存池替换时使用的算法,其开始一个循环次数上限为 tryCounter=NBuffers 的循环来检查缓存池里的空闲缓存块,当找到一个引用计数 refCount 0 但最近使用过( usage_count 不等于 0 )的缓存块时将 usage_count 1 ,接着重新设置 tryCounter=NBuffers 并继续遍历,直到有缓存块的 refCount usage_count 都为 0 ,则其最近较少使用,可以被替换掉。

 


------------
转载请著明出处,来自博客:
blog.csdn.net/beiigang
beigang.iteye.com
 

 

 

  • 大小: 68.2 KB
  • 大小: 119.2 KB
  • 大小: 115.9 KB
10
15
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics