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

Commit2802b02

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 parent9595bff commit2802b02

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
@@ -866,46 +866,83 @@ XLogRecPtr
866866
XLogFindNextRecord(XLogReaderState*state,XLogRecPtrRecPtr)
867867
{
868868
XLogReaderStatesaved_state=*state;
869-
XLogRecPtrtargetPagePtr;
870869
XLogRecPtrtmpRecPtr;
871-
inttargetRecOff;
872870
XLogRecPtrfound=InvalidXLogRecPtr;
873-
uint32pageHeaderSize;
874871
XLogPageHeaderheader;
875-
intreadLen;
876872
char*errormsg;
877873

878874
Assert(!XLogRecPtrIsInvalid(RecPtr));
879875

880-
targetRecOff=RecPtr %XLOG_BLCKSZ;
876+
/*
877+
* skip over potential continuation data, keeping in mind that it may span
878+
* multiple pages
879+
*/
880+
tmpRecPtr=RecPtr;
881+
while (true)
882+
{
883+
XLogRecPtrtargetPagePtr;
884+
inttargetRecOff;
885+
uint32pageHeaderSize;
886+
intreadLen;
881887

882-
/* scroll back to page boundary */
883-
targetPagePtr=RecPtr-targetRecOff;
888+
/*
889+
* Compute targetRecOff. It should typically be equal or greater than
890+
* short page-header since a valid record can't start anywhere before
891+
* that, except when caller has explicitly specified the offset that
892+
* falls somewhere there or when we are skipping multi-page
893+
* continuation record. It doesn't matter though because
894+
* ReadPageInternal() is prepared to handle that and will read at least
895+
* short page-header worth of data
896+
*/
897+
targetRecOff=tmpRecPtr %XLOG_BLCKSZ;
884898

885-
/* Read the page containing the record */
886-
readLen=ReadPageInternal(state,targetPagePtr,targetRecOff);
887-
if (readLen<0)
888-
gotoerr;
899+
/* scroll back to page boundary */
900+
targetPagePtr=tmpRecPtr-targetRecOff;
889901

890-
header= (XLogPageHeader)state->readBuf;
902+
/* Read the page containing the record */
903+
readLen=ReadPageInternal(state,targetPagePtr,targetRecOff);
904+
if (readLen<0)
905+
gotoerr;
891906

892-
pageHeaderSize=XLogPageHeaderSize(header);
907+
header=(XLogPageHeader)state->readBuf;
893908

894-
/* make sure we have enough data for the page header */
895-
readLen=ReadPageInternal(state,targetPagePtr,pageHeaderSize);
896-
if (readLen<0)
897-
gotoerr;
909+
pageHeaderSize=XLogPageHeaderSize(header);
898910

899-
/* skip over potential continuation data */
900-
if (header->xlp_info&XLP_FIRST_IS_CONTRECORD)
901-
{
902-
/* record headers are MAXALIGN'ed */
903-
tmpRecPtr=targetPagePtr+pageHeaderSize
904-
+MAXALIGN(header->xlp_rem_len);
905-
}
906-
else
907-
{
908-
tmpRecPtr=targetPagePtr+pageHeaderSize;
911+
/* make sure we have enough data for the page header */
912+
readLen=ReadPageInternal(state,targetPagePtr,pageHeaderSize);
913+
if (readLen<0)
914+
gotoerr;
915+
916+
/* skip over potential continuation data */
917+
if (header->xlp_info&XLP_FIRST_IS_CONTRECORD)
918+
{
919+
/*
920+
* If the length of the remaining continuation data is more than
921+
* what can fit in this page, the continuation record crosses over
922+
* this page. Read the next page and try again. xlp_rem_len in the
923+
* next page header will contain the remaining length of the
924+
* continuation data
925+
*
926+
* Note that record headers are MAXALIGN'ed
927+
*/
928+
if (MAXALIGN(header->xlp_rem_len)> (XLOG_BLCKSZ-pageHeaderSize))
929+
tmpRecPtr=targetPagePtr+XLOG_BLCKSZ;
930+
else
931+
{
932+
/*
933+
* The previous continuation record ends in this page. Set
934+
* tmpRecPtr to point to the first valid record
935+
*/
936+
tmpRecPtr=targetPagePtr+pageHeaderSize
937+
+MAXALIGN(header->xlp_rem_len);
938+
break;
939+
}
940+
}
941+
else
942+
{
943+
tmpRecPtr=targetPagePtr+pageHeaderSize;
944+
break;
945+
}
909946
}
910947

911948
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp