pg_control为什么会存在?
为啥会有pg_control这么个文件呢? pg_control是PostgreSQL中一个很重要的文件,我们之前讲到过PostgreSQL的启动过程,启动过程中很重要的一项工作就是故障恢复,启动startup进程,回放WAL日志进行故障恢复,而从哪里开始进行回放呢?我怎么知道起点在哪里呢?这个位置的保存一定是在磁盘中,而不是在内存中,假设数据库因故障崩溃,内存中的数据会丢失,所以,只有checkpointer进程在做checkpoint操作时不断的更新pg_control文件,使之持久化保存,数据库启动进行故障恢复时,读取该文件,获得故障恢复的起始位置。
除了保存检查点信息,还保存一些其他的状态等信息,用于数据库启动等。比如数据库状态信息,系统表版本号等。
看下面的代码,数据库启动时会检查pg_control文件,如果文件被损坏,数据库就会启动失败。
main()
--> MemoryContextInit() // 初始化内存上下文: TopMemoryContext、ErrorContext
--> PostmasterMain(argc, argv); // Postmaster main entry point
--> pqsignal_pm(SIGCHLD, reaper); /* handle child termination */ // 注册信号处理函数
--> checkDataDir(); // 检查数据目录
--> ValidatePgVersion(DataDir); // 检查PG_VERSION文件,PG实例版本是否与程序兼容
--> checkControlFile(); // 检查pg_control文件
--> CreateDataDirLockFile(true); // 创建postmaster.pid文件
--> LocalProcessControlFile(false); // 读pg_control,到ControlFileData中
--> ReadControlFile();
startup进程从pg_control中获取故障恢复起点:
StartupProcessMain(void)
--> StartupXLOG();
--> ValidateXLOGDirectoryStructure(); // 检查pg_wal是否存在
--> readRecoverySignalFile(); // 依据standby.signal和recovery.signal是否存在,判断进入何种状态
--> validateRecoveryParameters();
if (read_backup_label(&checkPointLoc, &backupEndRequired, &backupFromStandby))
{
// 如果backup_label文件存在,则表示从备份文件中进行恢复(例如使用pg_basebackup进行备份)
// 此种情况,设置backup_label,而不是用pg_control,为啥呢?下面就是解释
/*
* If we see a backup_label during recovery, we assume that we are recovering
* from a backup dump file, and we therefore roll forward from the checkpoint
* id