diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-11-22 12:53:59 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-11-22 13:07:23 +0200 |
commit | 1a3d104475ce01326fc00601ed66ac4d658e37e5 (patch) | |
tree | e20102123012e30c84b9d1be83f184f62c505742 | |
parent | f4482a542c30034c7871fd35050128823ef5c6d5 (diff) | |
download | postgresql-1a3d104475ce01326fc00601ed66ac4d658e37e5.tar.gz postgresql-1a3d104475ce01326fc00601ed66ac4d658e37e5.zip |
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.
-rwxr-xr-x[-rw-r--r--] | src/backend/access/transam/xlog.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a95149b9399..de19d2240fc 100644..100755 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7367,13 +7367,13 @@ RecoveryInProgress(void) return false; 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; - /* spinlock is essential on machines with weak memory ordering! */ - SpinLockAcquire(&xlogctl->info_lck); LocalRecoveryInProgress = xlogctl->SharedRecoveryInProgress; - SpinLockRelease(&xlogctl->info_lck); /* * Initialize TimeLineID and RedoRecPtr when we discover that recovery @@ -7382,7 +7382,20 @@ RecoveryInProgress(void) * this, see also LocalSetXLogInsertAllowed.) */ 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(); + } + /* + * 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; } |