On 21.05.2013 00:00, Simon Riggs wrote:
When we set the new timeline we should be updating all values that
might be used elsewhere. If we do that, then no matter when or how we
run GetXLogReplayRecPtr, it can't ever get it wrong in any backend.

--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -5838,8 +5838,16 @@ StartupXLOG(void)
        }

        /* Save the selected TimeLineID in shared memory, too */
-       XLogCtl->ThisTimeLineID = ThisTimeLineID;
-       XLogCtl->PrevTimeLineID = PrevTimeLineID;
+       {
+               /* use volatile pointer to prevent code rearrangement */
+               volatile XLogCtlData *xlogctl = XLogCtl;
+
+               SpinLockAcquire(&xlogctl->info_lck);
+               XLogCtl->ThisTimeLineID = ThisTimeLineID;
+               XLogCtl->lastReplayedTLI = ThisTimeLineID;
+               XLogCtl->PrevTimeLineID = PrevTimeLineID;
+               SpinLockRelease(&xlogctl->info_lck);
+       }

Hmm. lastReplayedTLI is supposed to be the timeline of the last record that was replayed, ie. the timeline corresponding lastReplayedEndRecPtr. I think it would work, but it feels like it could be an easy source of bugs in the future.

It might be a good idea to change walsender to not store that in ThisTimeLineID, though. It used to make sense for ThisTimeLineID to track the current recovery timeline in 9.2 and below, but now that walsender can be sending any older timeline, using ThisTimeLineID to store the latest one seems confusing.

- Heikki


--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to