From 1a3d104475ce01326fc00601ed66ac4d658e37e5 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas <heikki.linnakangas@iki.fi> Date: Fri, 22 Nov 2013 12:53:59 +0200 Subject: [PATCH] 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. --- src/backend/access/transam/xlog.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) mode change 100644 => 100755 src/backend/access/transam/xlog.c diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c old mode 100644 new mode 100755 index a95149b9399..de19d2240fc --- 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; } -- GitLab