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

Commit 1a3d104

Browse files
committed
Avoid acquiring spinlock when checking if recovery has finished, for speed.
RecoveryIsInProgress() can be called very frequently. During normal operation, it just checks a backend-local variable and returns quickly, but during hot standby, it checks a spinlock-protected shared variable. Those spinlock acquisitions can become a point of contention on a busy hot standby system. Replace the spinlock acquisition with a memory barrier. Per discussion with Andres Freund, Ants Aasma and Merlin Moncure.
1 parent f4482a5 commit 1a3d104

File tree

1 file changed

+17
-4
lines changed
  • src/backend/access/transam

1 file changed

+17
-4
lines changed

src/backend/access/transam/xlog.c

100644100755
+17-4
Original file line numberDiff line numberDiff line change
@@ -7367,13 +7367,13 @@ RecoveryInProgress(void)
73677367
return false;
73687368
else
73697369
{
7370-
/* use volatile pointer to prevent code rearrangement */
7370+
/*
7371+
* use volatile pointer to make sure we make a fresh read of the
7372+
* shared variable.
7373+
*/
73717374
volatile XLogCtlData *xlogctl = XLogCtl;
73727375

7373-
/* spinlock is essential on machines with weak memory ordering! */
7374-
SpinLockAcquire(&xlogctl->info_lck);
73757376
LocalRecoveryInProgress = xlogctl->SharedRecoveryInProgress;
7376-
SpinLockRelease(&xlogctl->info_lck);
73777377

73787378
/*
73797379
* Initialize TimeLineID and RedoRecPtr when we discover that recovery
@@ -7382,7 +7382,20 @@ RecoveryInProgress(void)
73827382
* this, see also LocalSetXLogInsertAllowed.)
73837383
*/
73847384
if (!LocalRecoveryInProgress)
7385+
{
7386+
/*
7387+
* If we just exited recovery, make sure we read TimeLineID and
7388+
* RedoRecPtr after SharedRecoveryInProgress (for machines with
7389+
* weak memory ordering).
7390+
*/
7391+
pg_memory_barrier();
73857392
InitXLOGAccess();
7393+
}
7394+
/*
7395+
* Note: We don't need a memory barrier when we're still in recovery.
7396+
* We might exit recovery immediately after return, so the caller
7397+
* can't rely on 'true' meaning that we're still in recovery anyway.
7398+
*/
73867399

73877400
return LocalRecoveryInProgress;
73887401
}

0 commit comments

Comments
 (0)