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

Commit7dfb9b4

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 parentb09caec commit7dfb9b4

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
@@ -844,46 +844,83 @@ XLogRecPtr
844844
XLogFindNextRecord(XLogReaderState*state,XLogRecPtrRecPtr)
845845
{
846846
XLogReaderStatesaved_state=*state;
847-
XLogRecPtrtargetPagePtr;
848847
XLogRecPtrtmpRecPtr;
849-
inttargetRecOff;
850848
XLogRecPtrfound=InvalidXLogRecPtr;
851-
uint32pageHeaderSize;
852849
XLogPageHeaderheader;
853-
intreadLen;
854850
char*errormsg;
855851

856852
Assert(!XLogRecPtrIsInvalid(RecPtr));
857853

858-
targetRecOff=RecPtr %XLOG_BLCKSZ;
854+
/*
855+
* skip over potential continuation data, keeping in mind that it may span
856+
* multiple pages
857+
*/
858+
tmpRecPtr=RecPtr;
859+
while (true)
860+
{
861+
XLogRecPtrtargetPagePtr;
862+
inttargetRecOff;
863+
uint32pageHeaderSize;
864+
intreadLen;
859865

860-
/* scroll back to page boundary */
861-
targetPagePtr=RecPtr-targetRecOff;
866+
/*
867+
* Compute targetRecOff. It should typically be equal or greater than
868+
* short page-header since a valid record can't start anywhere before
869+
* that, except when caller has explicitly specified the offset that
870+
* falls somewhere there or when we are skipping multi-page
871+
* continuation record. It doesn't matter though because
872+
* ReadPageInternal() is prepared to handle that and will read at least
873+
* short page-header worth of data
874+
*/
875+
targetRecOff=tmpRecPtr %XLOG_BLCKSZ;
862876

863-
/* Read the page containing the record */
864-
readLen=ReadPageInternal(state,targetPagePtr,targetRecOff);
865-
if (readLen<0)
866-
gotoerr;
877+
/* scroll back to page boundary */
878+
targetPagePtr=tmpRecPtr-targetRecOff;
867879

868-
header= (XLogPageHeader)state->readBuf;
880+
/* Read the page containing the record */
881+
readLen=ReadPageInternal(state,targetPagePtr,targetRecOff);
882+
if (readLen<0)
883+
gotoerr;
869884

870-
pageHeaderSize=XLogPageHeaderSize(header);
885+
header=(XLogPageHeader)state->readBuf;
871886

872-
/* make sure we have enough data for the page header */
873-
readLen=ReadPageInternal(state,targetPagePtr,pageHeaderSize);
874-
if (readLen<0)
875-
gotoerr;
887+
pageHeaderSize=XLogPageHeaderSize(header);
876888

877-
/* skip over potential continuation data */
878-
if (header->xlp_info&XLP_FIRST_IS_CONTRECORD)
879-
{
880-
/* record headers are MAXALIGN'ed */
881-
tmpRecPtr=targetPagePtr+pageHeaderSize
882-
+MAXALIGN(header->xlp_rem_len);
883-
}
884-
else
885-
{
886-
tmpRecPtr=targetPagePtr+pageHeaderSize;
889+
/* make sure we have enough data for the page header */
890+
readLen=ReadPageInternal(state,targetPagePtr,pageHeaderSize);
891+
if (readLen<0)
892+
gotoerr;
893+
894+
/* skip over potential continuation data */
895+
if (header->xlp_info&XLP_FIRST_IS_CONTRECORD)
896+
{
897+
/*
898+
* If the length of the remaining continuation data is more than
899+
* what can fit in this page, the continuation record crosses over
900+
* this page. Read the next page and try again. xlp_rem_len in the
901+
* next page header will contain the remaining length of the
902+
* continuation data
903+
*
904+
* Note that record headers are MAXALIGN'ed
905+
*/
906+
if (MAXALIGN(header->xlp_rem_len)> (XLOG_BLCKSZ-pageHeaderSize))
907+
tmpRecPtr=targetPagePtr+XLOG_BLCKSZ;
908+
else
909+
{
910+
/*
911+
* The previous continuation record ends in this page. Set
912+
* tmpRecPtr to point to the first valid record
913+
*/
914+
tmpRecPtr=targetPagePtr+pageHeaderSize
915+
+MAXALIGN(header->xlp_rem_len);
916+
break;
917+
}
918+
}
919+
else
920+
{
921+
tmpRecPtr=targetPagePtr+pageHeaderSize;
922+
break;
923+
}
887924
}
888925

889926
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp