]> granicus.if.org Git - postgresql/commitdiff
Install recycled WAL segments with current timeline ID during recovery.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 30 Apr 2013 13:31:21 +0000 (16:31 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 30 Apr 2013 14:50:10 +0000 (17:50 +0300)
This is a follow-up to the earlier fix, which changed the recycling logic
to recycle WAL segments under the current recovery target timeline. That
turns out to be a bad idea, because installing a recycled segment with
a TLI higher than what we're recovering at the moment means that the recovery
logic will find the recycled WAL segment and try to replay it. It will fail,
but but the mere presence of such a WAL segment will mask any other, real,
file with the same log/seg, but smaller TLI.

Per report from Mitsumasa Kondo. Apply to 9.1 and 9.2, like the previous
fix. Master was already doing this differently; this patch makes 9.1 and
9.2 to do the same thing as master.

src/backend/access/transam/xlog.c

index 4c96afa0f3cf4e5da9d64d4696f62f643ab6d2b7..dd7d1a22b4bed73176315668458a7aa6749977ed 100644 (file)
@@ -8261,10 +8261,18 @@ CreateRestartPoint(int flags)
                PrevLogSeg(_logId, _logSeg);
 
                /*
-                * Update ThisTimeLineID to the recovery target timeline, so that
-                * we install any recycled segments on the correct timeline.
+                * 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.
                 */
-               ThisTimeLineID = GetRecoveryTargetTLI();
+               SpinLockAcquire(&xlogctl->info_lck);
+               ThisTimeLineID = XLogCtl->lastCheckPoint.ThisTimeLineID;
+               SpinLockRelease(&xlogctl->info_lck);
 
                RemoveOldXlogFiles(_logId, _logSeg, endptr);