千家信息网

PostgreSQL启动恢复读取checkpoint记录失败的条件

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,1、首先读取ControlFile->checkPoint指向的checkpoint2、如果读取失败,slave直接abort退出,master再次读取ControlFile->prevCheckPo
千家信息网最后更新 2026年11月01日PostgreSQL启动恢复读取checkpoint记录失败的条件
1、首先读取ControlFile->checkPoint指向的checkpoint2、如果读取失败,slave直接abort退出,master再次读取ControlFile->prevCheckPoint指向的checkpointStartupXLOG->    |--checkPointLoc = ControlFile->checkPoint;    |--record = ReadCheckpointRecord(xlogreader, checkPointLoc, 1, true):    |-- if (record != NULL){           ...        }else if (StandbyMode){            ereport(PANIC,(errmsg("could not locate a valid checkpoint record")));        }else{            checkPointLoc = ControlFile->prevCheckPoint;            record = ReadCheckpointRecord(xlogreader, checkPointLoc, 2, true);            if (record != NULL){                InRecovery = true;//标记下面进入recovery            }else{                ereport(PANIC,(errmsg("could not locate a valid checkpoint record")));            }        }

一、那么什么条件下读取的checkpoint记录record==NULL?

1、ControlFile->checkPoint % XLOG_BLCKSZ < SizeOfXLogShortPHD2、ReadRecord(xlogreader, ControlFile->checkPoint, LOG, true)返回NULL3、ReadRecord读到的record!=NULL && record->xl_rmid != RM_XLOG_ID4、ReadRecord读到的record!=NULL && info != XLOG_CHECKPOINT_SHUTDOWN && info != XLOG_CHECKPOINT_ONLINE5、ReadRecord读到的record!=NULL && record->xl_tot_len != SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(CheckPoint)

二、ReadRecord函数返回NULL的条件

ReadRecord(xlogreader, ControlFile->checkPoint, LOG, true)    |--record = XLogReadRecord(xlogreader, ControlFile->checkPoint, &errormsg);    |-- 2.1 record==NULL && !StandbyMode    |-- 2.2 record!=NULL && !tliInHistory(xlogreader->latestPageTLI, expectedTLEs)    /*-----    note:只要读取了一页xlog,就会赋值为该页第一个记录的时间线    XLogReaderValidatePageHeader        -->xlogreader->latestPageTLI=hdr->xlp_tli;    ------*/

三、XlogReadRecord读取checkpoint返回NULL的条件?

XLogReadRecord(xlogreader, ControlFile->checkPoint, &errormsg)    targetPagePtr = ControlFile->checkPoint - (ControlFile->checkPoint % XLOG_BLCKSZ);    targetRecOff = ControlFile->checkPoint % XLOG_BLCKSZ;    readOff = ReadPageInternal(state,targetPagePtr, Min(targetRecOff + SizeOfXLogRecord, XLOG_BLCKSZ));    pageHeaderSize = XLogPageHeaderSize((XLogPageHeader) state->readBuf);    record = (XLogRecord *) (state->readBuf + RecPtr % XLOG_BLCKSZ);    total_len = record->xl_tot_len;    -------------    1、readOff < 0    2、0< targetRecOff < pageHeaderSize    3、(((XLogPageHeader) state->readBuf)->xlp_info & XLP_FIRST_IS_CONTRECORD) && targetRecOff == pageHeaderSize       page头有跨页的record并且checkpoint定位的偏移正好在页头尾部    4、targetRecOff <= XLOG_BLCKSZ - SizeOfXLogRecord &&        !ValidXLogRecordHeader(state, ControlFile->checkPoint, state->ReadRecPtr, record,randAccess)       ---(record->xl_tot_len < SizeOfXLogRecord || record->xl_rmid > RM_MAX_ID || record->xl_prev != state->ReadRecPtr)    5、targetRecOff > XLOG_BLCKSZ - SizeOfXLogRecord && total_len < SizeOfXLogRecord    6、total_len > state->readRecordBufSize && !allocate_recordbuf(state, total_len)       一旦该记录损坏,total_len的长度非常大的话,就需要allocate_recordbuf扩展state->readbuf,可能因此分配失败abort       记录的checksum需要等待全部读取完整记录后才校验    -------------

三、ReadPageInternal返回的readOff返回小于0的条件

ReadPageInternal(state,targetPagePtr, Min(targetRecOff + SizeOfXLogRecord, XLOG_BLCKSZ))    1、第一次read wal文件,readLen = state->read_page:读取第一页。readLen < 0    2、readLen>0 && !XLogReaderValidatePageHeader(state, targetSegmentPtr, state->readBuf)    --    3、读取checkpoint所在页readLen = state->read_page: readLen < 0    4、readLen > 0 && readLen <= SizeOfXLogShortPHD    5、!XLogReaderValidatePageHeader(state, pageptr, (char *) hdr)

四、XLogPageRead何时返回值<0 ?

/*    1、WaitForWALToBecomeAvailable open失败    2、lseek 失败 && !StandbyMode    3、read失败 && !StandbyMode    4、校验page头失败 && !StandbyMode    如果是StandbyMode,则会重新retry->WaitForWALToBecomeAvailable,切换日志源进行open    */    !WaitForWALToBecomeAvailable(targetPagePtr + reqLen,private->randAccess,1,targetRecPtr)//open    |-- return -1    readOff = targetPageOff;    if (lseek(readFile, (off_t) readOff, SEEK_SET) < 0){        !StandbyMode:: return -1    }    if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ){        !StandbyMode:: return -1    }    XLogReaderValidatePageHeader(xlogreader, targetPagePtr, readBuf)    !StandbyMode:: return -1

五、WaitForWALToBecomeAvailable何时返回false?

--XLOG_FROM_ARCHIVE | XLOG_FROM_PG_WAL    1、先XLogFileReadAnyTLI open日志:        1、遍历时间线列表里的每一个时间线,从最新的开始        2、当读取checkpoint的时候,source是XLOG_FROM_ANY        3、先找归档的日志进行open;如果open失败再找WAL日志进行open        4、如果都没有open成功,则向前找时间线,open前一个时间线segno和文件号相同的文件进行open        5、open成功后expectedTLEs被赋值为当前时间线列表的所有值    2、如果open失败,则切换日志源:XLOG_FROM_ARCHIVE | XLOG_FROM_PG_WAL -> XLOG_FROM_STREAM    3、切换日志源后,XLOG_FROM_ARCHIVE | XLOG_FROM_PG_WAL 则:       slave && promote :return false       !StandbyMode:return false    --XLOG_FROM_STREAM    1、!WalRcvStreaming()即receiver进程挂了,切换日志源    2、CheckForStandbyTrigger()切换日志源    3、XLOG_FROM_STREAM->XLOG_FROM_ARCHIVE
日志 时间 切换 条件 文件 成功 指向 相同 再次 函数 尾部 所在 时候 标记 第一次 线列 表里 进程 长度 偏移 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳九邦互联网科技有限公司 广州大一互联网络科技有限公司 互联网科技公司起名 互联网科技工作委员会副主任毛军 科技赋能下的互联网金融 互联网科技巨头监管 科技平台互联网 互联网下的科技发展 浩特互联网科技 长亮科技 互联网金融 天扬科技互联网广告 科技赋能互联网健康 互联网科技创新服务 河南猎农互联网科技有限公司 和信科技工业互联网 电子科技大学互联网创业大赛 广州新华互联网科技学校电竞方面 美国互联网科技实力 互联网科技手机排行榜 互联网领先科技活动 北京路客互联网科技有限公司 万易互联网科技有限公司 互联网实体化科技化 北京大学互联网科技怎么样 互联网校园科技培训 厦门比较好的科技互联网公司 崇明区互联网教育科技售后服务 互联网科技快讯热点 美国五大互联网科技公司市值多少 好易买互联网科技
0