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

Commit cf8a489

Browse files
committed
Allow WAL summarization to back up when timeline changes.
The old code believed that it was not possible to switch timelines without first replaying all of the WAL from the old timeline, but that turns out to be false, as demonstrated by an example from Fujii Masao. As a result, it assumed that summarization would always continue from the LSN where summarization previously ended. But in fact, when a timeline switch occurs without replaying all the WAL from the previous timeline, we can need to back up to an earlier LSN. Adjust accordingly. Discussion: https://postgr.es/m/CA+TgmoZGEsZodXC4f=XZNkAeyuDmWTSkpkjCEOcF19Am0mt_OA@mail.gmail.com
1 parent 857df3c commit cf8a489

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

src/backend/postmaster/walsummarizer.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -388,13 +388,27 @@ WalSummarizerMain(char *startup_data, size_t startup_data_len)
388388

389389
/*
390390
* If we've reached the switch LSN, we can't summarize anything else
391-
* on this timeline. Switch to the next timeline and go around again.
391+
* on this timeline. Switch to the next timeline and go around again,
392+
* backing up to the exact switch point if we passed it.
392393
*/
393394
if (!XLogRecPtrIsInvalid(switch_lsn) && current_lsn >= switch_lsn)
394395
{
396+
/* Restart summarization from switch point. */
395397
current_tli = switch_tli;
398+
current_lsn = switch_lsn;
399+
400+
/* Next timeline and switch point, if any, not yet known. */
396401
switch_lsn = InvalidXLogRecPtr;
397402
switch_tli = 0;
403+
404+
/* Update (really, rewind, if needed) state in shared memory. */
405+
LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
406+
WalSummarizerCtl->summarized_lsn = current_lsn;
407+
WalSummarizerCtl->summarized_tli = current_tli;
408+
WalSummarizerCtl->lsn_is_exact = true;
409+
WalSummarizerCtl->pending_lsn = current_lsn;
410+
LWLockRelease(WALSummarizerLock);
411+
398412
continue;
399413
}
400414

@@ -415,7 +429,6 @@ WalSummarizerMain(char *startup_data, size_t startup_data_len)
415429

416430
/* Update state in shared memory. */
417431
LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
418-
Assert(WalSummarizerCtl->pending_lsn <= end_of_summary_lsn);
419432
WalSummarizerCtl->summarized_lsn = end_of_summary_lsn;
420433
WalSummarizerCtl->summarized_tli = current_tli;
421434
WalSummarizerCtl->lsn_is_exact = true;
@@ -1060,7 +1073,6 @@ SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact,
10601073

10611074
/* Also update shared memory. */
10621075
LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
1063-
Assert(summary_end_lsn >= WalSummarizerCtl->pending_lsn);
10641076
Assert(summary_end_lsn >= WalSummarizerCtl->summarized_lsn);
10651077
WalSummarizerCtl->pending_lsn = summary_end_lsn;
10661078
LWLockRelease(WALSummarizerLock);
@@ -1460,17 +1472,11 @@ summarizer_read_local_xlog_page(XLogReaderState *state,
14601472
* Allow reads up to exactly the switch point.
14611473
*
14621474
* It's possible that this will cause read_upto to move
1463-
* backwards, because walreceiver might have read a
1464-
* partial record and flushed it to disk, and we'd view
1465-
* that data as safe to read. However, the
1466-
* XLOG_END_OF_RECOVERY record will be written at the end
1467-
* of the last complete WAL record, not at the end of the
1468-
* WAL that we've flushed to disk.
1469-
*
1470-
* So switchpoint < private->read_upto is possible here,
1471-
* but switchpoint < state->EndRecPtr should not be.
1475+
* backwards, because we might have been promoted before
1476+
* reaching the end of the previous timeline. In that case,
1477+
* the next loop iteration will likely conclude that we've
1478+
* reached end of WAL.
14721479
*/
1473-
Assert(switchpoint >= state->EndRecPtr);
14741480
private_data->read_upto = switchpoint;
14751481

14761482
/* Debugging output. */

0 commit comments

Comments
 (0)