Skip to content

Commit be9788e

Browse files
committed
Avoid unnecessary acquisition of SyncRepLock in transaction commit time.
In SyncRepWaitForLSN() routine called in transaction commit time, SyncRepLock is necessary to atomically both check the shared sync_standbys_defined flag and operate the sync replication wait-queue. On the other hand, when the flag is false, the lock is not necessary because the wait-queue is not touched. But due to the changes by commit 48c9f49, previously the lock was taken whatever the flag was. This could cause unnecessary performance overhead in every transaction commit time. Therefore this commit avoids that unnecessary aquisition of SyncRepLock. Author: Fujii Masao Reviewed-by: Asim Praveen, Masahiko Sawada, Discussion: https://postgr.es/m/20200406050332.nsscfqjzk2d57zyx@alap3.anarazel.de
1 parent 05c16b8 commit be9788e

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

src/backend/replication/syncrep.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,18 +158,30 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
158158
*/
159159
Assert(InterruptHoldoffCount > 0);
160160

161+
/*
162+
* Fast exit if user has not requested sync replication, or there are no
163+
* sync replication standby names defined.
164+
*
165+
* Since this routine gets called every commit time, it's important to
166+
* exit quickly if sync replication is not requested. So we check
167+
* WalSndCtl->sync_standbys_defined flag without the lock and exit
168+
* immediately if it's false. If it's true, we need to check it again later
169+
* while holding the lock, to check the flag and operate the sync rep
170+
* queue atomically. This is necessary to avoid the race condition
171+
* described in SyncRepUpdateSyncStandbysDefined(). On the other
172+
* hand, if it's false, the lock is not necessary because we don't touch
173+
* the queue.
174+
*/
175+
if (!SyncRepRequested() ||
176+
!((volatile WalSndCtlData *) WalSndCtl)->sync_standbys_defined)
177+
return;
178+
161179
/* Cap the level for anything other than commit to remote flush only. */
162180
if (commit)
163181
mode = SyncRepWaitMode;
164182
else
165183
mode = Min(SyncRepWaitMode, SYNC_REP_WAIT_FLUSH);
166184

167-
/*
168-
* Fast exit if user has not requested sync replication.
169-
*/
170-
if (!SyncRepRequested())
171-
return;
172-
173185
Assert(SHMQueueIsDetached(&(MyProc->syncRepLinks)));
174186
Assert(WalSndCtl != NULL);
175187

0 commit comments

Comments
 (0)