diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index df1e341c76..c30ebaa0a6 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -158,18 +158,27 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit) */ Assert(InterruptHoldoffCount > 0); + /* + * Fast exit if user has not requested sync replication, or there are no + * sync replication standby names defined. + * + * Since this routine gets called every commit time, it's important to + * exit quickly if sync replication is not requested. So we check + * WalSndCtl->sync_standbys_define without the lock and exit + * immediately if it's false. If it's true, we check it again later + * while holding the lock, to avoid the race condition described + * in SyncRepUpdateSyncStandbysDefined(). + */ + if (!SyncRepRequested() || + !((volatile WalSndCtlData *) WalSndCtl)->sync_standbys_defined) + return; + /* Cap the level for anything other than commit to remote flush only. */ if (commit) mode = SyncRepWaitMode; else mode = Min(SyncRepWaitMode, SYNC_REP_WAIT_FLUSH); - /* - * Fast exit if user has not requested sync replication. - */ - if (!SyncRepRequested()) - return; - Assert(SHMQueueIsDetached(&(MyProc->syncRepLinks))); Assert(WalSndCtl != NULL);