Hi, While working on something else, I noticed that the proc array group XID clearing leader resets procArrayGroupNext of all the followers atomically along with procArrayGroupMember. ISTM that it's enough for the followers to exit the wait loop and continue if the leader resets just procArrayGroupMember, the followers can reset procArrayGroupNext by themselves. This relieves the leader a bit, especially when there are many followers, as it avoids a bunch of atomic writes and pg_write_barrier() for the leader .
I'm attaching a small patch with the above change. It doesn't seem to break anything, the cirrus-ci members are happy https://github.com/BRupireddy/postgres/tree/allow_processes_to_reset_proc_array_v1. It doesn't seem to show visible benefit on my system, nor hurt anyone in my testing [1]. Thoughts? [1] # of clients HEAD PATCHED 1 31661 31512 2 67134 66789 4 135084 132372 8 254174 255384 16 418598 420903 32 491922 494183 64 509824 509451 128 513298 512838 256 505191 496266 512 465208 453588 768 431304 425736 1024 398110 397352 2048 308732 308901 4096 200355 219480 -- Bharath Rupireddy PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com
From 097e74e5d1477e6670cf1bcb9316a4a850c960ba Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Date: Wed, 23 Nov 2022 14:08:19 +0000 Subject: [PATCH v1] Allow processes to reset procArrayGroupNext themselves instead of leader --- src/backend/storage/ipc/procarray.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 06918759e7..459ac8ead9 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -826,7 +826,9 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid) } pgstat_report_wait_end(); - Assert(pg_atomic_read_u32(&proc->procArrayGroupNext) == INVALID_PGPROCNO); + Assert(pg_atomic_read_u32(&proc->procArrayGroupNext) != INVALID_PGPROCNO); + + pg_atomic_write_u32(&proc->procArrayGroupNext, INVALID_PGPROCNO); /* Fix semaphore count for any absorbed wakeups */ while (extraWaits-- > 0) @@ -874,10 +876,6 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid) PGPROC *nextproc = &allProcs[wakeidx]; wakeidx = pg_atomic_read_u32(&nextproc->procArrayGroupNext); - pg_atomic_write_u32(&nextproc->procArrayGroupNext, INVALID_PGPROCNO); - - /* ensure all previous writes are visible before follower continues. */ - pg_write_barrier(); nextproc->procArrayGroupMember = false; -- 2.34.1