Fix recycling of WAL segments after switching timeline during recovery.

This was broken before, we would recycle old WAL segments on wrong timeline
after the recovery target timeline had changed, but my recent commit to
not initialize ThisTimeLineID at all in a standby's checkpointer process
broke this completely.

The problem is that when installing a recycled WAL segment as a future one,
ThisTimeLineID is used to construct the filename. To fix, always update
ThisTimeLineID to the current timeline being recovered, before recycling
WAL segments at a restartpoint.

This still leaves a small window where we might install WAL segments under
wrong timeline ID, if the timeline is changed just as we're about to start
recycling. Also, even if we're replaying timeline X at the momnent, there's
no guarantee that we'll need as many WAL segments on that timeline as we
recycle. We might be just about to reach the point where we switch to next
timeline, so might only need one more WAL segment on the current timeline.
We'll live with the waste in that situation.

Bug pointed out by Fujii Masao. 9.1 and 9.2 had the same issue, when
recovery target timeline was changed, but I committed a slightly different
version of this patch on those branches.
This commit is contained in:
Heikki Linnakangas 2012-12-20 22:00:34 +02:00
parent dc9896a245
commit 343ee00b73
1 changed files with 13 additions and 0 deletions

View File

@ -7637,6 +7637,19 @@ CreateRestartPoint(int flags)
KeepLogSeg(endptr, &_logSegNo);
_logSegNo--;
/*
* Update ThisTimeLineID to the timeline we're currently replaying,
* so that we install any recycled segments on that timeline.
*
* There is no guarantee that the WAL segments will be useful on the
* current timeline; if recovery proceeds to a new timeline right
* after this, the pre-allocated WAL segments on this timeline will
* not be used, and will go wasted until recycled on the next
* restartpoint. We'll live with that.
*/
(void) GetXLogReplayRecPtr(&ThisTimeLineID);
RemoveOldXlogFiles(_logSegNo, endptr);
/*