mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
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.
This commit is contained in:
parent
f4482a542c
commit
1a3d104475
21
src/backend/access/transam/xlog.c
Normal file → Executable file
21
src/backend/access/transam/xlog.c
Normal file → Executable file
@ -7367,13 +7367,13 @@ RecoveryInProgress(void)
|
|||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* use volatile pointer to prevent code rearrangement */
|
/*
|
||||||
|
* use volatile pointer to make sure we make a fresh read of the
|
||||||
|
* shared variable.
|
||||||
|
*/
|
||||||
volatile XLogCtlData *xlogctl = XLogCtl;
|
volatile XLogCtlData *xlogctl = XLogCtl;
|
||||||
|
|
||||||
/* spinlock is essential on machines with weak memory ordering! */
|
|
||||||
SpinLockAcquire(&xlogctl->info_lck);
|
|
||||||
LocalRecoveryInProgress = xlogctl->SharedRecoveryInProgress;
|
LocalRecoveryInProgress = xlogctl->SharedRecoveryInProgress;
|
||||||
SpinLockRelease(&xlogctl->info_lck);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize TimeLineID and RedoRecPtr when we discover that recovery
|
* Initialize TimeLineID and RedoRecPtr when we discover that recovery
|
||||||
@ -7382,7 +7382,20 @@ RecoveryInProgress(void)
|
|||||||
* this, see also LocalSetXLogInsertAllowed.)
|
* this, see also LocalSetXLogInsertAllowed.)
|
||||||
*/
|
*/
|
||||||
if (!LocalRecoveryInProgress)
|
if (!LocalRecoveryInProgress)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we just exited recovery, make sure we read TimeLineID and
|
||||||
|
* RedoRecPtr after SharedRecoveryInProgress (for machines with
|
||||||
|
* weak memory ordering).
|
||||||
|
*/
|
||||||
|
pg_memory_barrier();
|
||||||
InitXLOGAccess();
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
return LocalRecoveryInProgress;
|
return LocalRecoveryInProgress;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user