Log messages for replication slot acquisition and release.

This commit log messages (at LOG level when log_replication_commands is
set, otherwise at DEBUG1 level) when walsenders acquire and release
replication slots. These messages help to know the lifetime of a
replication slot - one can know how long a streaming standby, logical
subscriber, or replication slot consumer is down. These messages will be
useful on production servers to debug and analyze inactive replication
slots.

Note that these messages are emitted only for walsenders but not for
backends. This is because walsenders are the ones that typically hold
replication slots for longer durations, unlike backends which hold them
for executing replication related functions.

Author: Bharath Rupireddy
Reviewed-by: Peter Smith, Amit Kapila, Alvaro Herrera
Discussion: http://postgr.es/m/CALj2ACX17G7F-jeLt+7KhJ6YxVeRwR8Zk0rDh4VnT546o0UpTQ@mail.gmail.com
This commit is contained in:
Amit Kapila 2023-11-21 07:59:53 +05:30
parent 07cb29737a
commit 7c3fb505b1
2 changed files with 36 additions and 5 deletions

View File

@ -7510,11 +7510,12 @@ log_line_prefix = '%m [%p] %q%u@%d/%a '
</term> </term>
<listitem> <listitem>
<para> <para>
Causes each replication command to be logged in the server log. Causes each replication command and <literal>walsender</literal>
See <xref linkend="protocol-replication"/> for more information about process's replication slot acquisition/release to be logged in the
replication command. The default value is <literal>off</literal>. server log. See <xref linkend="protocol-replication"/> for more
Only superusers and users with the appropriate <literal>SET</literal> information about replication command. The default value is
privilege can change this setting. <literal>off</literal>. Only superusers and users with the appropriate
<literal>SET</literal> privilege can change this setting.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -537,6 +537,16 @@ retry:
*/ */
if (SlotIsLogical(s)) if (SlotIsLogical(s))
pgstat_acquire_replslot(s); pgstat_acquire_replslot(s);
if (am_walsender)
{
ereport(log_replication_commands ? LOG : DEBUG1,
SlotIsLogical(s)
? errmsg("acquired logical replication slot \"%s\"",
NameStr(s->data.name))
: errmsg("acquired physical replication slot \"%s\"",
NameStr(s->data.name)));
}
} }
/* /*
@ -549,9 +559,17 @@ void
ReplicationSlotRelease(void) ReplicationSlotRelease(void)
{ {
ReplicationSlot *slot = MyReplicationSlot; ReplicationSlot *slot = MyReplicationSlot;
char *slotname = NULL; /* keep compiler quiet */
bool is_logical = false; /* keep compiler quiet */
Assert(slot != NULL && slot->active_pid != 0); Assert(slot != NULL && slot->active_pid != 0);
if (am_walsender)
{
slotname = pstrdup(NameStr(slot->data.name));
is_logical = SlotIsLogical(slot);
}
if (slot->data.persistency == RS_EPHEMERAL) if (slot->data.persistency == RS_EPHEMERAL)
{ {
/* /*
@ -596,6 +614,18 @@ ReplicationSlotRelease(void)
MyProc->statusFlags &= ~PROC_IN_LOGICAL_DECODING; MyProc->statusFlags &= ~PROC_IN_LOGICAL_DECODING;
ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
LWLockRelease(ProcArrayLock); LWLockRelease(ProcArrayLock);
if (am_walsender)
{
ereport(log_replication_commands ? LOG : DEBUG1,
is_logical
? errmsg("released logical replication slot \"%s\"",
slotname)
: errmsg("released physical replication slot \"%s\"",
slotname));
pfree(slotname);
}
} }
/* /*