diff options
Diffstat (limited to 'src/backend/access')
-rw-r--r-- | src/backend/access/transam/xlog.c | 63 |
1 files changed, 17 insertions, 46 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 69cd5e9d426..72aeb42961f 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -350,8 +350,14 @@ XLogRecPtr XactLastCommitEnd = InvalidXLogRecPtr; * XLogCtl->Insert.RedoRecPtr, whenever we can safely do so (ie, when we * hold an insertion lock). See XLogInsertRecord for details. We are also * allowed to update from XLogCtl->RedoRecPtr if we hold the info_lck; - * see GetRedoRecPtr. A freshly spawned backend obtains the value during - * InitXLOGAccess. + * see GetRedoRecPtr. + * + * NB: Code that uses this variable must be prepared not only for the + * possibility that it may be arbitrarily out of date, but also for the + * possibility that it might be set to InvalidXLogRecPtr. We used to + * initialize it as a side effect of the first call to RecoveryInProgress(), + * which meant that most code that might use it could assume that it had a + * real if perhaps stale value. That's no longer the case. */ static XLogRecPtr RedoRecPtr; @@ -359,6 +365,12 @@ static XLogRecPtr RedoRecPtr; * doPageWrites is this backend's local copy of (forcePageWrites || * fullPageWrites). It is used together with RedoRecPtr to decide whether * a full-page image of a page need to be taken. + * + * NB: Initially this is false, and there's no guarantee that it will be + * initialized to any other value before it is first used. Any code that + * makes use of it must recheck the value after obtaining a WALInsertLock, + * and respond appropriately if it turns out that the previous value wasn't + * accurate. */ static bool doPageWrites; @@ -8390,9 +8402,6 @@ PerformRecoveryXLogAction(void) * * Unlike testing InRecovery, this works in any process that's connected to * shared memory. - * - * As a side-effect, we initialize the local RedoRecPtr variable the first - * time we see that recovery is finished. */ bool RecoveryInProgress(void) @@ -8415,23 +8424,6 @@ RecoveryInProgress(void) LocalRecoveryInProgress = (xlogctl->SharedRecoveryState != RECOVERY_STATE_DONE); /* - * Initialize TimeLineID and RedoRecPtr when we discover that recovery - * is finished. InitPostgres() relies upon this behaviour to ensure - * that InitXLOGAccess() is called at backend startup. (If you change - * this, see also LocalSetXLogInsertAllowed.) - */ - if (!LocalRecoveryInProgress) - { - /* - * If we just exited recovery, make sure we read TimeLineID and - * RedoRecPtr after SharedRecoveryState (for machines with weak - * memory ordering). - */ - pg_memory_barrier(); - InitXLOGAccess(); - } - - /* * Note: We don't need a memory barrier when we're still in recovery. * We might exit recovery immediately after return, so the caller * can't rely on 'true' meaning that we're still in recovery anyway. @@ -8547,9 +8539,6 @@ LocalSetXLogInsertAllowed(void) LocalXLogInsertAllowed = 1; - /* Initialize as RecoveryInProgress() would do when switching state */ - InitXLOGAccess(); - return oldXLogAllowed; } @@ -8657,25 +8646,6 @@ ReadCheckpointRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr, } /* - * This must be called in a backend process before creating WAL records - * (except in a standalone backend, which does StartupXLOG instead). We need - * to initialize the local copy of RedoRecPtr. - */ -void -InitXLOGAccess(void) -{ - XLogCtlInsert *Insert = &XLogCtl->Insert; - - /* set wal_segment_size */ - wal_segment_size = ControlFile->xlog_seg_size; - - /* Use GetRedoRecPtr to copy the RedoRecPtr safely */ - (void) GetRedoRecPtr(); - /* Also update our copy of doPageWrites. */ - doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites); -} - -/* * Return the current Redo pointer from shared memory. * * As a side-effect, the local RedoRecPtr copy is updated. @@ -8706,8 +8676,9 @@ GetRedoRecPtr(void) * full-page image to be included in the WAL record. * * The returned values are cached copies from backend-private memory, and - * possibly out-of-date. XLogInsertRecord will re-check them against - * up-to-date values, while holding the WAL insert lock. + * possibly out-of-date or, indeed, uninitalized, in which case they will + * be InvalidXLogRecPtr and false, respectively. XLogInsertRecord will + * re-check them against up-to-date values, while holding the WAL insert lock. */ void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p) |