postgresql/src/include/replication
Andres Freund bc971f4025 Optimize walsender wake up logic using condition variables
WalSndWakeup() currently loops through all the walsenders slots, with a
spinlock acquisition and release for every iteration, to wake up waiting
walsenders.

This commonly was not a problem before e101dfac3a. But, to allow logical
decoding on standbys, we need to wake up logical walsenders after every WAL
record is applied on the standby, rather just when flushing WAL or switching
timelines.  This causes a performance regression for workloads replaying a lot
of WAL records.

To solve this, we use condition variable (CV) to efficiently wake up
walsenders in WalSndWakeup().

Every walsender prepares to sleep on a shared memory CV. Note that it just
prepares to sleep on the CV (i.e., adds itself to the CV's waitlist), but does
not actually wait on the CV (IOW, it never calls ConditionVariableSleep()). It
still uses WaitEventSetWait() for waiting, because CV infrastructure doesn't
handle FeBe socket events currently. The processes (startup process,
walreceiver etc.)  wanting to wake up walsenders use
ConditionVariableBroadcast(), which in turn calls SetLatch(), helping
walsenders come out of WaitEventSetWait().

We use separate shared memory CVs for physical and logical walsenders for
selective wake ups, see WalSndWakeup() for more details.

This approach is simple and reasonably efficient. But not very elegant. But
for 16 it seems to be a better path than a larger redesign of the CV
mechanism.  A desirable future improvement would be to add support for CVs
into WaitEventSetWait().

This still leaves us with a small regression in very extreme workloads (due to
the spinlock acquisition in ConditionVariableBroadcast() when there are no
waiters) - but that seems acceptable.

Reported-by: Andres Freund <andres@anarazel.de>
Suggested-by: Andres Freund <andres@anarazel.de>
Author: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Reviewed-by: "Drouvot, Bertrand" <bertranddrouvot.pg@gmail.com>
Reviewed-by: Zhijie Hou <houzj.fnst@fujitsu.com>
Discussion: https://www.postgresql.org/message-id/20230509190247.3rrplhdgem6su6cg%40awork3.anarazel.de
2023-05-21 09:44:55 -07:00
..
decode.h Update copyright for 2023 2023-01-02 15:00:37 -05:00
logical.h Update copyright for 2023 2023-01-02 15:00:37 -05:00
logicallauncher.h Track logrep apply workers' last start times to avoid useless waits. 2023-01-22 14:08:46 -05:00
logicalproto.h Perform apply of large transactions by parallel workers. 2023-01-09 07:52:45 +05:30
logicalrelation.h Allow the use of indexes other than PK and REPLICA IDENTITY on the subscriber. 2023-03-15 08:49:04 +05:30
logicalworker.h Perform apply of large transactions by parallel workers. 2023-01-09 07:52:45 +05:30
message.h Update copyright for 2023 2023-01-02 15:00:37 -05:00
origin.h Perform apply of large transactions by parallel workers. 2023-01-09 07:52:45 +05:30
output_plugin.h Fix some typos and some incorrectly duplicated words 2023-04-18 14:03:49 +12:00
pgoutput.h Perform apply of large transactions by parallel workers. 2023-01-09 07:52:45 +05:30
reorderbuffer.h Pre-beta mechanical code beautification. 2023-05-19 17:24:48 -04:00
slot.h Support invalidating replication slots due to horizon and wal_level 2023-04-07 22:40:27 -07:00
snapbuild.h Update copyright for 2023 2023-01-02 15:00:37 -05:00
syncrep.h Update copyright for 2023 2023-01-02 15:00:37 -05:00
walreceiver.h Add new predefined role pg_create_subscription. 2023-03-30 11:37:19 -04:00
walsender.h For cascading replication, wake physical and logical walsenders separately 2023-04-08 01:06:00 -07:00
walsender_private.h Optimize walsender wake up logic using condition variables 2023-05-21 09:44:55 -07:00
worker_internal.h Fix invalid memory access during the shutdown of the parallel apply worker. 2023-05-09 09:28:06 +05:30