Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5833306

Browse files
committed
Fix pg_xlogdump so that it handles cross-page XLP_FIRST_IS_CONTRECORD record.
Previously pg_xlogdump failed to dump the contents of the WAL fileif the file starts with the continuation WAL record which spansmore than one pages. Since pg_xlogdump assumed that the continuationrecord always fits on a page, it could not find the valid WAL record tostart reading from in that case.This patch changes pg_xlogdump so that it can handle a continuationWAL record which crosses a page boundary and find the valid recordto start reading from.Back-patch to 9.3 where pg_xlogdump was introduced.Author: Pavan DeolaseeReviewed-By: Michael Paquier and Craig RingerDiscussion: CABOikdPsPByMiG6J01DKq6om2+BNkxHTPkOyqHM2a4oYwGKsqQ@mail.gmail.com
1 parent68bd9f7 commit5833306

File tree

1 file changed

+64
-27
lines changed

1 file changed

+64
-27
lines changed

‎src/backend/access/transam/xlogreader.c

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -911,47 +911,84 @@ XLogRecPtr
911911
XLogFindNextRecord(XLogReaderState*state,XLogRecPtrRecPtr)
912912
{
913913
XLogReaderStatesaved_state=*state;
914-
XLogRecPtrtargetPagePtr;
915914
XLogRecPtrtmpRecPtr;
916-
inttargetRecOff;
917915
XLogRecPtrfound=InvalidXLogRecPtr;
918-
uint32pageHeaderSize;
919916
XLogPageHeaderheader;
920917
XLogRecord*record;
921-
intreadLen;
922918
char*errormsg;
923919

924920
Assert(!XLogRecPtrIsInvalid(RecPtr));
925921

926-
targetRecOff=RecPtr %XLOG_BLCKSZ;
922+
/*
923+
* skip over potential continuation data, keeping in mind that it may span
924+
* multiple pages
925+
*/
926+
tmpRecPtr=RecPtr;
927+
while (true)
928+
{
929+
XLogRecPtrtargetPagePtr;
930+
inttargetRecOff;
931+
uint32pageHeaderSize;
932+
intreadLen;
927933

928-
/* scroll back to page boundary */
929-
targetPagePtr=RecPtr-targetRecOff;
934+
/*
935+
* Compute targetRecOff. It should typically be equal or greater than
936+
* short page-header since a valid record can't start anywhere before
937+
* that, except when caller has explicitly specified the offset that
938+
* falls somewhere there or when we are skipping multi-page
939+
* continuation record. It doesn't matter though because
940+
* ReadPageInternal() is prepared to handle that and will read at least
941+
* short page-header worth of data
942+
*/
943+
targetRecOff=tmpRecPtr %XLOG_BLCKSZ;
930944

931-
/* Read the page containing the record */
932-
readLen=ReadPageInternal(state,targetPagePtr,targetRecOff);
933-
if (readLen<0)
934-
gotoerr;
945+
/* scroll back to page boundary */
946+
targetPagePtr=tmpRecPtr-targetRecOff;
935947

936-
header= (XLogPageHeader)state->readBuf;
948+
/* Read the page containing the record */
949+
readLen=ReadPageInternal(state,targetPagePtr,targetRecOff);
950+
if (readLen<0)
951+
gotoerr;
937952

938-
pageHeaderSize=XLogPageHeaderSize(header);
953+
header=(XLogPageHeader)state->readBuf;
939954

940-
/* make sure we have enough data for the page header */
941-
readLen=ReadPageInternal(state,targetPagePtr,pageHeaderSize);
942-
if (readLen<0)
943-
gotoerr;
955+
pageHeaderSize=XLogPageHeaderSize(header);
944956

945-
/* skip over potential continuation data */
946-
if (header->xlp_info&XLP_FIRST_IS_CONTRECORD)
947-
{
948-
/* record headers are MAXALIGN'ed */
949-
tmpRecPtr=targetPagePtr+pageHeaderSize
950-
+MAXALIGN(header->xlp_rem_len);
951-
}
952-
else
953-
{
954-
tmpRecPtr=targetPagePtr+pageHeaderSize;
957+
/* make sure we have enough data for the page header */
958+
readLen=ReadPageInternal(state,targetPagePtr,pageHeaderSize);
959+
if (readLen<0)
960+
gotoerr;
961+
962+
/* skip over potential continuation data */
963+
if (header->xlp_info&XLP_FIRST_IS_CONTRECORD)
964+
{
965+
/*
966+
* If the length of the remaining continuation data is more than
967+
* what can fit in this page, the continuation record crosses over
968+
* this page. Read the next page and try again. xlp_rem_len in the
969+
* next page header will contain the remaining length of the
970+
* continuation data
971+
*
972+
* Note that record headers are MAXALIGN'ed
973+
*/
974+
if (MAXALIGN(header->xlp_rem_len)> (XLOG_BLCKSZ-pageHeaderSize))
975+
tmpRecPtr=targetPagePtr+XLOG_BLCKSZ;
976+
else
977+
{
978+
/*
979+
* The previous continuation record ends in this page. Set
980+
* tmpRecPtr to point to the first valid record
981+
*/
982+
tmpRecPtr=targetPagePtr+pageHeaderSize
983+
+MAXALIGN(header->xlp_rem_len);
984+
break;
985+
}
986+
}
987+
else
988+
{
989+
tmpRecPtr=targetPagePtr+pageHeaderSize;
990+
break;
991+
}
955992
}
956993

957994
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp