Commit bc153c94 authored by Amit Kapila's avatar Amit Kapila

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 2c03216d and
2076db2a.  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
parent 514a731d
...@@ -944,7 +944,7 @@ static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt); ...@@ -944,7 +944,7 @@ static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt);
* *
* If 'fpw_lsn' is valid, it is the oldest LSN among the pages that this * If 'fpw_lsn' is valid, it is the oldest LSN among the pages that this
* WAL record applies to, that were not included in the record as full page * WAL record applies to, that were not included in the record as full page
* images. If fpw_lsn >= RedoRecPtr, the function does not perform the * images. If fpw_lsn <= RedoRecPtr, the function does not perform the
* insertion and returns InvalidXLogRecPtr. The caller can then recalculate * insertion and returns InvalidXLogRecPtr. The caller can then recalculate
* which pages need a full-page image, and retry. If fpw_lsn is invalid, the * which pages need a full-page image, and retry. If fpw_lsn is invalid, the
* record is always inserted. * record is always inserted.
...@@ -977,6 +977,7 @@ XLogInsertRecord(XLogRecData *rdata, ...@@ -977,6 +977,7 @@ XLogInsertRecord(XLogRecData *rdata,
info == XLOG_SWITCH); info == XLOG_SWITCH);
XLogRecPtr StartPos; XLogRecPtr StartPos;
XLogRecPtr EndPos; XLogRecPtr EndPos;
bool prevDoPageWrites = doPageWrites;
/* we assume that all of the record header is in the first chunk */ /* we assume that all of the record header is in the first chunk */
Assert(rdata->len >= SizeOfXLogRecord); Assert(rdata->len >= SizeOfXLogRecord);
...@@ -1024,10 +1025,14 @@ XLogInsertRecord(XLogRecData *rdata, ...@@ -1024,10 +1025,14 @@ XLogInsertRecord(XLogRecData *rdata,
WALInsertLockAcquire(); WALInsertLockAcquire();
/* /*
* Check to see if my copy of RedoRecPtr or doPageWrites is out of date. * Check to see if my copy of RedoRecPtr is out of date. If so, may have
* If so, may have to go back and have the caller recompute everything. * to go back and have the caller recompute everything. This can only
* This can only happen just after a checkpoint, so it's better to be slow * happen just after a checkpoint, so it's better to be slow in this case
* in this case and fast otherwise. * and fast otherwise.
*
* Also check to see if fullPageWrites or forcePageWrites was just turned
* on; if we weren't already doing full-page writes then go back and
* recompute.
* *
* If we aren't doing full-page writes then RedoRecPtr doesn't actually * If we aren't doing full-page writes then RedoRecPtr doesn't actually
* affect the contents of the XLOG record, so we'll update our local copy * affect the contents of the XLOG record, so we'll update our local copy
...@@ -1042,7 +1047,9 @@ XLogInsertRecord(XLogRecData *rdata, ...@@ -1042,7 +1047,9 @@ XLogInsertRecord(XLogRecData *rdata,
} }
doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites); doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
if (fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr && doPageWrites) if (doPageWrites &&
(!prevDoPageWrites ||
(fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr)))
{ {
/* /*
* Oops, some buffer now needs to be backed up that the caller didn't * Oops, some buffer now needs to be backed up that the caller didn't
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment