From fc53b36e62c76bb29ad201842a7a6c1bdb94b6da Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Thu, 15 Sep 2022 05:05:22 +0000 Subject: [PATCH v7] Add LOG messages when replication slots become active and inactive These logs will be extremely useful on production servers to debug and analyze inactive replication slot issues. --- doc/src/sgml/config.sgml | 7 +++--- src/backend/replication/slot.c | 17 ++++++++++++++ src/backend/replication/walsender.c | 35 +++++++++++++++++++++++++++++ src/backend/utils/misc/guc_tables.c | 2 +- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 700914684d..55976b3df8 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -7482,9 +7482,10 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' - Causes each replication command to be logged in the server log. - See for more information about - replication command. The default value is off. + Causes each replication command and related activity to be logged in + the server log. See for more + information about replication command. The default value is + off. Only superusers and users with the appropriate SET privilege can change this setting. diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index 8fec1cb4a5..9814fc87de 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -180,8 +180,25 @@ ReplicationSlotShmemExit(int code, Datum arg) { /* Make sure active replication slots are released */ if (MyReplicationSlot != NULL) + { + bool is_physical; + char slotname[NAMEDATALEN] = {0}; + + is_physical = SlotIsPhysical(MyReplicationSlot); + strcpy(slotname, NameStr(MyReplicationSlot->data.name)); + ReplicationSlotRelease(); + if (is_physical) + ereport(log_replication_commands ? LOG : DEBUG3, + (errmsg("released physical replication slot \"%s\"", + slotname))); + else + ereport(log_replication_commands ? LOG : DEBUG3, + (errmsg("released logical replication slot \"%s\"", + slotname))); + } + /* Also cleanup all the temporary slots. */ ReplicationSlotCleanup(); } diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 724010dbd9..3daaea362a 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -322,8 +322,25 @@ WalSndErrorCleanup(void) wal_segment_close(xlogreader); if (MyReplicationSlot != NULL) + { + bool is_physical; + char slotname[NAMEDATALEN] = {0}; + + is_physical = SlotIsPhysical(MyReplicationSlot); + strcpy(slotname, NameStr(MyReplicationSlot->data.name)); + ReplicationSlotRelease(); + if (is_physical) + ereport(log_replication_commands ? LOG : DEBUG3, + (errmsg("released physical replication slot \"%s\"", + slotname))); + else + ereport(log_replication_commands ? LOG : DEBUG3, + (errmsg("released logical replication slot \"%s\"", + slotname))); + } + ReplicationSlotCleanup(); replication_active = false; @@ -704,6 +721,10 @@ StartReplication(StartReplicationCmd *cmd) (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot use a logical replication slot for physical replication"))); + ereport(log_replication_commands ? LOG : DEBUG3, + (errmsg("acquired physical replication slot \"%s\"", + cmd->slotname))); + /* * We don't need to verify the slot's restart_lsn here; instead we * rely on the caller requesting the starting point to use. If the @@ -844,8 +865,14 @@ StartReplication(StartReplicationCmd *cmd) } if (cmd->slotname) + { ReplicationSlotRelease(); + ereport(log_replication_commands ? LOG : DEBUG3, + (errmsg("released physical replication slot \"%s\"", + cmd->slotname))); + } + /* * Copy is finished now. Send a single-row result set indicating the next * timeline. @@ -1256,6 +1283,10 @@ StartLogicalReplication(StartReplicationCmd *cmd) cmd->slotname), errdetail("This slot has been invalidated because it exceeded the maximum reserved size."))); + ereport(log_replication_commands ? LOG : DEBUG3, + (errmsg("acquired logical replication slot \"%s\"", + cmd->slotname))); + /* * Force a disconnect, so that the decoding code doesn't need to care * about an eventual switch from running in recovery, to running in a @@ -1318,6 +1349,10 @@ StartLogicalReplication(StartReplicationCmd *cmd) FreeDecodingContext(logical_decoding_ctx); ReplicationSlotRelease(); + ereport(log_replication_commands ? LOG : DEBUG3, + (errmsg("released logical replication slot \"%s\"", + cmd->slotname))); + replication_active = false; if (got_STOPPING) proc_exit(0); diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 550e95056c..da1f90b4fa 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -1177,7 +1177,7 @@ struct config_bool ConfigureNamesBool[] = }, { {"log_replication_commands", PGC_SUSET, LOGGING_WHAT, - gettext_noop("Logs each replication command."), + gettext_noop("Logs each replication command and related activity."), NULL }, &log_replication_commands, -- 2.34.1