StartupXLOG函数流程
第一步从checkpoint xlog记录中提取信息,更新共享内存变量,比如nextFullXid、nextOid、oidCount。
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
设置下一个要分配的 MultiXactId 和偏移量。当我们可以从检查点记录中准确地确定正确的下一个 ID/偏移量时,就会使用它。 虽然这仅在引导和 XLog 重放期间调用,但我们会锁定以防任何热备后端(hot-standby backends)正在检查这些值。在二进制升级期间,请确保偏移量 SLRU 足够大以包含将要创建的下一个值。我们需要在二进制升级模式的第一次启动期间尽早执行此操作:实际上是在 StartupMultiXact() 之前,因为该例程甚至在 StartupXLOG() 之前就被调用了。 我们不能早于此时执行此操作,因为在此例程的第一次调用期间,我们确定了 MaybeExtendOffsetSlru 需要的 MultiXactState->nextMXact 值。
AdvanceOldestClogXid函数将最旧的有效阻塞条目的集群范围值提前(Advance the cluster-wide value for the oldest valid clog entry)。 我们必须获取 CLogTruncationLock 来推进最旧的 ClogXid。 在实际阻塞截断期间没有必要持有锁,只有当我们提前限制时,因为查找任意 xid 的代码需要从测试 oldClogXid 到完成阻塞查找时持有 CLogTruncationLock。
第二步初始化复制槽、启动logical状态MultiXact、启动CommitTs和启动ReplicationOrigin 。
StartupReplicationSlots函数在服务器启动时将所有复制槽从磁盘加载到内存中。 这需要在我们开始崩溃恢复之前运行。
StartupReorderBuffer函数在我们重新启动/崩溃后删除所有溢出到磁盘的数据。 当相应的插槽被重用时,它将被重新创建。
StartupMultiXact函数必须在 postmaster 或独立后端启动期间调用一次。StartupXLOG 已经通过调用 MultiXactSetNextMXact 和/或 MultiXactAdvanceNextMXact 建立了 nextMXact/nextOffset,以及来自 pg_control 和/或 MultiXactAdvanceOldest 的 oldMulti 信息,但我们还没有重放 WAL。
StartupCommitTs函数必须在 postmaster 或独立后端启动期间调用一次,在 StartupXLOG 初始化 ShmemVariableCache->nextFullXid 之后。
StartupReplicationOrigin函数从 CheckPointReplicationOrigin 之前保存的检查点数据中恢复复制重播状态(Recover replication replay status)。这只需要在启动时调用,而不在之后恢复期间(例如,在 HS 或来自基本备份的 PITR 中)读取的每个检查点期间调用。 此后的所有状态都可以通过查看提交记录来恢复。
第三步初始化未记录的 LSN,我们必须使用创建它们的相同 TimeLineID 重放 WAL 条目,因此暂时采用检查点指示的 TLI。
第四步主要调用两个函数restoreTimeLineHistoryFiles和restoreTwoPhaseData。
restoreTimeLineHistoryFiles将“现在”和恢复目标时间线之间的任何缺失时间线历史文件从存档复制到 pg_wal。 虽然我们自己不需要这些文件 - 恢复目标时间线的历史文件也涵盖了历史中所有以前的时间线 - 级联备用服务器可能对它们感兴趣。 或者,如果您将此服务器中的 WAL 存档到与主服务器不同的存档中,则最好在故障转移后将所有历史文件存档到那里,这样您就可以使用旧时间线之一作为 PITR 目标。 时间线历史文件很小,因此最好不必要地复制它们,而不是不复制它们然后后悔。
restoreTwoPhaseData在恢复运行之前,扫描 pg_twophase 并填写其状态,以便能够处理重做生成的条目。 在采取任何恢复操作之前进行扫描具有丢弃比要重放的第一条记录更新的任何 2PC 文件的优点,从而避免重放时的任何冲突。 这也避免了在恢复磁盘上的两阶段数据时进行的任何后续扫描。