背景
大部分人對 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