Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fd4f2af

Browse files
author
Amit Kapila
committed
Attach FPI to the first record after full_page_writes is turned on.
XLogInsert fails to attach a required FPI to the first record after full_page_writes is turned on by the last checkpoint. This bug got introduced in 9.5 due to code rearrangement in commits 2c03216 and 2076db2. Fix it by ensuring that XLogInsertRecord performs a recomputation when the given record is generated with FPW as off but found that the flag has been turned on while actually inserting the record. Reported-by: Kyotaro Horiguchi Author: Kyotaro Horiguchi Reviewed-by: Amit Kapila Backpatch-through: 9.5 where this problem was introduced Discussion: https://postgr.es/m/20180420.151043.74298611.horiguchi.kyotaro@lab.ntt.co.jp
1 parent 4659632 commit fd4f2af

File tree

1 file changed

+13
-6
lines changed
  • src/backend/access/transam

1 file changed

+13
-6
lines changed

src/backend/access/transam/xlog.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt);
915915
*
916916
* If 'fpw_lsn' is valid, it is the oldest LSN among the pages that this
917917
* WAL record applies to, that were not included in the record as full page
918-
* images. If fpw_lsn >= RedoRecPtr, the function does not perform the
918+
* images. If fpw_lsn <= RedoRecPtr, the function does not perform the
919919
* insertion and returns InvalidXLogRecPtr. The caller can then recalculate
920920
* which pages need a full-page image, and retry. If fpw_lsn is invalid, the
921921
* record is always inserted.
@@ -942,6 +942,7 @@ XLogInsertRecord(XLogRecData *rdata, XLogRecPtr fpw_lsn)
942942
rechdr->xl_info == XLOG_SWITCH);
943943
XLogRecPtr StartPos;
944944
XLogRecPtr EndPos;
945+
bool prevDoPageWrites = doPageWrites;
945946

946947
/* we assume that all of the record header is in the first chunk */
947948
Assert(rdata->len >= SizeOfXLogRecord);
@@ -989,10 +990,14 @@ XLogInsertRecord(XLogRecData *rdata, XLogRecPtr fpw_lsn)
989990
WALInsertLockAcquire();
990991

991992
/*
992-
* Check to see if my copy of RedoRecPtr or doPageWrites is out of date.
993-
* If so, may have to go back and have the caller recompute everything.
994-
* This can only happen just after a checkpoint, so it's better to be slow
995-
* in this case and fast otherwise.
993+
* Check to see if my copy of RedoRecPtr is out of date. If so, may have
994+
* to go back and have the caller recompute everything. This can only
995+
* happen just after a checkpoint, so it's better to be slow in this case
996+
* and fast otherwise.
997+
*
998+
* Also check to see if fullPageWrites or forcePageWrites was just turned
999+
* on; if we weren't already doing full-page writes then go back and
1000+
* recompute.
9961001
*
9971002
* If we aren't doing full-page writes then RedoRecPtr doesn't actually
9981003
* affect the contents of the XLOG record, so we'll update our local copy
@@ -1007,7 +1012,9 @@ XLogInsertRecord(XLogRecData *rdata, XLogRecPtr fpw_lsn)
10071012
}
10081013
doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
10091014

1010-
if (fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr && doPageWrites)
1015+
if (doPageWrites &&
1016+
(!prevDoPageWrites ||
1017+
(fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr)))
10111018
{
10121019
/*
10131020
* Oops, some buffer now needs to be backed up that the caller didn't

0 commit comments

Comments
 (0)