千家信息网

PostgreSQL问题分析1:时间线不一致

发表于:2024-11-22 作者:千家信息网编辑
千家信息网最后更新 2024年11月22日,一、问题:requested timeline %u does not contain minimum recovery point %X/%X on timeline %u该日志在代码中的位置如下:
千家信息网最后更新 2024年11月22日PostgreSQL问题分析1:时间线不一致

一、问题:requested timeline %u does not contain minimum recovery point %X/%X on timeline %u

该日志在代码中的位置如下:

StartupXLOG:    if (!XLogRecPtrIsInvalid(ControlFile->minRecoveryPoint) &&        tliOfPointInHistory(ControlFile->minRecoveryPoint - 1, expectedTLEs) !=        ControlFile->minRecoveryPointTLI)        ereport(FATAL,                (errmsg("requested timeline %u does not contain minimum recovery point %X/%X on timeline %u",                        recoveryTargetTLI,                        (uint32) (ControlFile->minRecoveryPoint >> 32),                        (uint32) ControlFile->minRecoveryPoint,                        ControlFile->minRecoveryPointTLI)));

二、分析

recoveryTargetTLI这个值是什么呢?

1、改值在启动恢复过程中变化如下:

StartupXLOG:    ...    if (ControlFile->minRecoveryPointTLI > ControlFile->checkPointCopy.ThisTimeLineID)        recoveryTargetTLI = ControlFile->minRecoveryPointTLI;    else        recoveryTargetTLI = ControlFile->checkPointCopy.ThisTimeLineID;    readRecoveryCommandFile();    |-- for (item = head; item; item = item->next){    |       ...    |       else if (strcmp(item->name, "recovery_target_timeline") == 0){    |           rtliGiven = true;    |           if (strcmp(item->value, "latest") == 0)    |               rtli = 0;    |           else    |               rtli = (TimeLineID) strtoul(item->value, NULL, 0);    |       }    |       ...    |   }    |   ...    |   if (rtliGiven){    |       if (rtli){    |           recoveryTargetTLI = rtli;    |           recoveryTargetIsLatest = false;    |       }else{    |           recoveryTargetTLI = findNewestTimeLine(recoveryTargetTLI);    |           recoveryTargetIsLatest = true;    |       }    |-- }

首先,pg_control文件记录的最小恢复点时间线ControlFile->minRecoveryPointTLI会和pg_control文件记录的checkpoint的的时间线 ControlFile->checkPointCopy.ThisTimeLineID比较,recoveryTargetTLI取两者之间较大值。

然后readRecoveryCommandFile会读取recovery.cnf文件,如果是主机则没有recovery.cnf文件。recovery.cnf文件中recovery_target_timeline的值指定恢复到的时间线,如果是latest则时间线rtli为0否则为其指定值;如果rtli是指定值,则recoveryTargetTLI为指定值,否则从第一步获取的recoveryTargetTLI值+1开始,看是否有其对于的history文件,找到最大时间线对于的history文件,recoveryTargetTLI为该时间线。

0