Toggle logical decoding dynamically based on logical slot presence.

Previously logical decoding required wal_level to be set to 'logical'
at server start. This meant that users had to incur the overhead of
logical-level WAL logging even when no logical replication slots were
in use.

This commit adds functionality to automatically control logical
decoding availability based on logical replication slot presence. The
newly introduced module logicalctl.c allows logical decoding to be
dynamically activated when needed when wal_level is set to
'replica'.

When the first logical replication slot is created, the system
automatically increases the effective WAL level to maintain
logical-level WAL records. Conversely, after the last logical slot is
dropped or invalidated, it decreases back to 'replica' WAL level.

While activation occurs synchronously right after creating the first
logical slot, deactivation happens asynchronously through the
checkpointer process. This design avoids a race condition at the end
of recovery; a concurrent deactivation could happen while the startup
process enables logical decoding at the end of recovery, but WAL
writes are still not permitted until recovery fully completes. The
checkpointer will handle it after recovery is done. Asynchronous
deactivation also avoids excessive toggling of the logical decoding
status in workloads that repeatedly create and drop a single logical
slot. On the other hand, this lazy approach can delay changes to
effective_wal_level and the disabling logical decoding, especially
when the checkpointer is busy with other tasks. We chose this lazy
approach in all deactivation paths to keep the implementation simple,
even though laziness is strictly required only for end-of-recovery
cases. Future work might address this limitation either by using a
dedicated worker instead of the checkpointer, or by implementing
synchronous waiting during slot drops if workloads are significantly
affected by the lazy deactivation of logical decoding.

The effective WAL level, determined internally by XLogLogicalInfo, is
allowed to change within a transaction until an XID is assigned. Once
an XID is assigned, the value becomes fixed for the remainder of the
transaction. This behavior ensures that the logging mode remains
consistent within a writing transaction, similar to the behavior of
GUC parameters.

A new read-only GUC parameter effective_wal_level is introduced to
monitor the actual WAL level in effect. This parameter reflects the
current operational WAL level, which may differ from the configured
wal_level setting.

Bump PG_CONTROL_VERSION as it adds a new field to CheckPoint struct.

Reviewed-by: Shveta Malik <[email protected]>
Reviewed-by: Amit Kapila <[email protected]>
Reviewed-by: Hayato Kuroda <[email protected]>
Reviewed-by: Bertrand Drouvot <[email protected]>
Reviewed-by: Peter Smith <[email protected]>
Reviewed-by: Shlok Kyal <[email protected]>
Reviewed-by: Ashutosh Bapat <[email protected]>
Discussion: 
https://postgr.es/m/cad21aocvlelyq09pqpaws+jwdni5fuj8v2jgq-u9_ufbcp6...@mail.gmail.com

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/67c20979ce72b8c236622e5603f9775968ff501c

Modified Files
--------------
doc/src/sgml/config.sgml                           |  43 ++
doc/src/sgml/logical-replication.sgml              |   4 +-
doc/src/sgml/logicaldecoding.sgml                  |  45 +-
doc/src/sgml/ref/pg_createsubscriber.sgml          |  12 +-
doc/src/sgml/system-views.sgml                     |   5 +-
src/backend/access/heap/heapam.c                   |   8 +-
src/backend/access/rmgrdesc/xlogdesc.c             |  13 +-
src/backend/access/transam/xact.c                  |  27 +-
src/backend/access/transam/xlog.c                  | 105 +++-
src/backend/commands/publicationcmds.c             |  11 +-
src/backend/commands/tablecmds.c                   |   2 +-
src/backend/postmaster/checkpointer.c              |  19 +
src/backend/postmaster/postmaster.c                |   4 +-
src/backend/replication/logical/Makefile           |   1 +
src/backend/replication/logical/decode.c           |  41 +-
src/backend/replication/logical/logical.c          |  29 +-
src/backend/replication/logical/logicalctl.c       | 639 +++++++++++++++++++++
src/backend/replication/logical/meson.build        |   1 +
src/backend/replication/logical/slotsync.c         |   8 +-
src/backend/replication/slot.c                     | 186 +++++-
src/backend/replication/slotfuncs.c                |   7 +
src/backend/replication/walsender.c                |   7 +
src/backend/storage/ipc/ipci.c                     |   2 +
src/backend/storage/ipc/procsignal.c               |   3 +
src/backend/storage/ipc/standby.c                  |   7 +-
src/backend/utils/activity/wait_event_names.txt    |   1 +
src/backend/utils/cache/inval.c                    |   8 +-
src/backend/utils/init/postinit.c                  |   3 +
src/backend/utils/misc/guc_parameters.dat          |   9 +
src/backend/utils/misc/guc_tables.c                |   1 +
src/bin/pg_basebackup/pg_createsubscriber.c        |   6 +-
src/bin/pg_basebackup/t/040_pg_createsubscriber.pl |   2 -
src/bin/pg_upgrade/check.c                         |   6 +-
src/bin/pg_upgrade/t/002_pg_upgrade.pl             |   4 +
src/include/access/xlog.h                          |  17 +-
src/include/catalog/pg_control.h                   |   4 +-
src/include/replication/logicalctl.h               |  33 ++
src/include/replication/slot.h                     |   1 +
src/include/storage/lwlocklist.h                   |   1 +
src/include/storage/procsignal.h                   |   2 +
src/include/utils/guc_hooks.h                      |   1 +
src/test/recovery/meson.build                      |   1 +
.../recovery/t/035_standby_logical_decoding.pl     |   5 +-
src/test/recovery/t/051_effective_wal_level.pl     | 404 +++++++++++++
src/test/regress/expected/publication.out          |   4 -
src/test/subscription/t/001_rep_changes.pl         |   2 +-
src/tools/pgindent/typedefs.list                   |   1 +
47 files changed, 1599 insertions(+), 146 deletions(-)

Reply via email to