Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e369f37

Browse files
committed
Reduce the number of GetFlushRecPtr() calls done by walsenders.
Since the WAL flush position only moves forward, it's safe to cache its previous value within each walsender process, and update from shared memory only once we've caught up to the previously-seen value. When there are many active walsenders, this makes for a very significant reduction in the amount of contention on the XLogCtl->info_lck spinlock. This patch also adjusts the logic so that we update our idea of the flush position after processing a WAL record, rather than beforehand. This may cause us to realize we're not caught up when the preceding coding would've thought that we were, but that seems all to the good; it may avoid a useless sleep-and-wakeup cycle. Back-patch to v12. The contention problem exists in prior branches, but it's much less severe (due to inefficiencies elsewhere) so there seems no need to take any risk of back-patching further. Pierre Ducroquet, reviewed by Julien Rouhaud Discussion: https://postgr.es/m/2931018.Vxl9zapr77@pierred-pdoc
1 parent 20d6225 commit e369f37

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

src/backend/replication/walsender.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2774,7 +2774,14 @@ XLogSendLogical(void)
27742774
{
27752775
XLogRecord *record;
27762776
char *errm;
2777-
XLogRecPtr flushPtr;
2777+
2778+
/*
2779+
* We'll use the current flush point to determine whether we've caught up.
2780+
* This variable is static in order to cache it across calls. Caching is
2781+
* helpful because GetFlushRecPtr() needs to acquire a heavily-contended
2782+
* spinlock.
2783+
*/
2784+
static XLogRecPtr flushPtr = InvalidXLogRecPtr;
27782785

27792786
/*
27802787
* Don't know whether we've caught up yet. We'll set WalSndCaughtUp to
@@ -2791,11 +2798,6 @@ XLogSendLogical(void)
27912798
if (errm != NULL)
27922799
elog(ERROR, "%s", errm);
27932800

2794-
/*
2795-
* We'll use the current flush point to determine whether we've caught up.
2796-
*/
2797-
flushPtr = GetFlushRecPtr();
2798-
27992801
if (record != NULL)
28002802
{
28012803
/*
@@ -2808,7 +2810,16 @@ XLogSendLogical(void)
28082810
sentPtr = logical_decoding_ctx->reader->EndRecPtr;
28092811
}
28102812

2811-
/* Set flag if we're caught up. */
2813+
/*
2814+
* If first time through in this session, initialize flushPtr. Otherwise,
2815+
* we only need to update flushPtr if EndRecPtr is past it.
2816+
*/
2817+
if (flushPtr == InvalidXLogRecPtr)
2818+
flushPtr = GetFlushRecPtr();
2819+
else if (logical_decoding_ctx->reader->EndRecPtr >= flushPtr)
2820+
flushPtr = GetFlushRecPtr();
2821+
2822+
/* If EndRecPtr is still past our flushPtr, it means we caught up. */
28122823
if (logical_decoding_ctx->reader->EndRecPtr >= flushPtr)
28132824
WalSndCaughtUp = true;
28142825

0 commit comments

Comments
 (0)