Conditions under which PostgreSQL initiates recovery and fails to read checkpoint records
1. First read the checkpoint2 pointed to by ControlFile- > checkPoint. If the reading fails, slave exits directly, and master reads the checkpointStartupXLOG- pointed to by ControlFile- > prevCheckPoint > again |-- 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;// tag to enter recovery} else {ereport (PANIC, (errmsg ("could not locate a valid checkpoint record"));}}
1. Under what conditions do you read the checkpoint record record==NULL?
1. ControlFile- > checkPoint XLOG_BLCKSZ
< SizeOfXLogShortPHD2、ReadRecord(xlogreader, ControlFile->CheckPoint, LOG, true) returns null & & record- > xl_rmid! = RM_XLOG_ID4 read by NULL3 and ReadRecord, null & & info! = XLOG_CHECKPOINT_SHUTDOWN & & info! = XLOG_CHECKPOINT_ONLINE5 read by ReadRecord, null & record- > xl_tot_len! = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof (CheckPoint) read by ReadRecord
Second, the condition that the ReadRecord function returns NULL.
ReadRecord (xlogreader, ControlFile- > checkPoint, LOG, true) |-- record= XLogReadRecord (xlogreader, ControlFile- > checkPoint, & errormsg);-- 2.1record==NULL & &! StandbyMode |-- 2.2 recordrecords null & &! tliInHistory (xlogreader- > latestPageTLI, expectedTLEs) / *-note: as long as a page of xlog is read, it will be assigned to the timeline of the first record on that page: XLogReaderValidatePageHeader-> xlogreader- > latestPageTLI=hdr- > xlp_tli;-* /
3. What are the conditions for XlogReadRecord to read checkpoint and return 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 has a spread record in the header and the offset of the checkpoint positioning is exactly at the end of the page 4, targetRecOff 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) once the record is corrupted and the length of the total_len is very large, the allocate_recordbuf extension state- > readbuf is required. Therefore, the checksum that failed to allocate the abort record may have to wait for all the full records to be read before checking-
3. The readOff returned by ReadPageInternal returns a condition that is less than 0
ReadPageInternal (state,targetPagePtr, Min (targetRecOff + SizeOfXLogRecord, XLOG_BLCKSZ)) 1. The first read wal file, readLen = state- > read_page: read the first page. ReadLen
< 0 2、readLen>0 & &! XLogReaderValidatePageHeader (state, targetSegmentPtr, state- > readBuf)-3. Read checkpoint page readLen = state- > read_page: readLen
< 0 4、readLen >0 & & readLen 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. After switching log sources, XLOG_FROM_ARCHIVE | XLOG_FROM_PG_WAL: slave & & promote: return false! StandbyMode:return false-- XLOG_FROM_STREAM 1,! WalRcvStreaming () means the receiver process is down. Switch log sources 2, CheckForStandbyTrigger () switch log sources 3, XLOG_FROM_STREAM- > XLOG_FROM_ARCHIVE