背景
大部分人对 PG 的 checkpoint 机制会熟悉一点,但是对 restartpoint 却不太熟悉,网上介绍这方面的文章也比较少。因此,本文将以 PG 14.7 的社区代码为基础,介绍 PG 中的 restartpoint 机制。
原理介绍
什么是 restartpoint
在了解 restartpoint 前,首先需要知道 checkpoint,可以参考这篇博文 https://blog.csdn.net/zxwsbg/article/details/115013885?spm=1001.2014.3001.5502
简单的介绍如下所示
- checkpoint: 主库用的,用来定期刷脏及其他一些功能,crash 后实例自动去找最新的一个 checkpoint ,从其中记录的 redo point 的 WAL 日志位点开始向后进行 redo;
- restartpoint:备库用的,和主库的 checkpoint 功能类似,备库的 checkpointer 进程会定期的做 restartpoint 进行刷脏,并记录一些位点,如果 crash 了直接从对应的位点开始向后进行 redo。
restartpoint 触发机制
有两种触发机制:
- 当距离做上一个 restartpoint 已经过去了
checkpoint_timeout
秒,并且主库又做了新的 checkpoint ,这时触发 restartpoint; - 备机 WAL 大小快要超过
max_wal_size
参数设定的值;
restartpoint 做了什么
checkpoint XLOG 重做
在上一节的触发机制 1 中,主库做了一个 checkpoint(非关机时的 checkpoint ),会写一条 XLOG_CHECKPOINT_ONLINE
类型日志。
备机的 startup 进程在 xlog_redo
函数中,会针对这种类型日志做日志回放,并在 RecoveryRestartPoint
函数中保存主库该 checkpoint 的相关位点信息——checkpoint 位点、redo point 位点等。
CreateRestartPoint 函数
如上文所述,备机的 checkpointer 进程会定期触发 CreateRestartPoint
函数。该函数主要做了以下内容:
- 使用最近一次 checkpoint WAL 中的 redopoint 位点、chckpoint WAL 位点更新自身的对应位点;
- 使用
CheckPointGuts
进行刷脏,将内存中的信息持久化到硬盘; - 更新 pg_controlfile 中的信息,并落盘;
- 进行 WAL 日志文件回收;
- 写 CSV 日志记录本次 restartpoint(如果设置了的话),更新进程的相关显示信息。
需要注意的是:restartpoint 不写 WAL。
参考资料
[1] https://www.postgresql.org/docs/current/wal-configuration.html