PostgreSQL启动恢复读取checkpoint记录失败的条件
发表于:2025-11-11 作者:千家信息网编辑
千家信息网最后更新 2025年11月11日,1、首先读取ControlFile->checkPoint指向的checkpoint2、如果读取失败,slave直接abort退出,master再次读取ControlFile->prevCheckPo
千家信息网最后更新 2025年11月11日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安全错误
数据库的锁怎样保障安全
数据库sql高级
惠州网络安全企业
鹰潭高性价比服务器大概费用
舆论引导 网络安全培训
dhl亦庄软件开发工资待遇
软件开发工程师口头语
家庭nas 路由服务器
明日之后如何获得北京服务器
技校计算机网络技术靠谱吗
网络安全告警降噪
网络安全方向大学排名
战地风云连接不上服务器
成华区团息网络技术工作室
社保局网络安全宣传周
网络安全 广州日报
数据库 (公司背景
网络安全知识竞赛所需软件
重庆惠普服务器续保
景区数字孪生软件开发
共建机制和网络安全
计算机网络技术需要c语言吗
怎么看数据库表字段是否唯一
网络安全员介绍ppt
行业管理软件开发平台
江苏省网络技术有限公司
代理服务器上国外网站加速软件
计算机网络安全期刊论文
公司网站 软件开发合同
数据库基本关系具有哪些性质试卷
广州三金网络技术有限公司