From 20762f88ad95ea1a3d09352e294993e0ab7d0d19 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 25 Mar 2026 11:02:17 +0900 Subject: [PATCH v2 2/2] Add trace_logical_decoding_messages GUC to control logical decoding logging This commit introduces a new GUC, trace_logical_decoding_messages, to control the logging of logical decoding debug messages. This is similar to the former trace_recovery_messages for recovery debug messages. This parameter overrides log_min_messages for logical decoding messages only and is intended for debugging. Valid values are DEBUG5 through DEBUG1, and LOG. Messages at the configured level or higher are logged as if they were at LOG level. The default is DEBUG1. Some logical decoding messages (e.g., "logical decoding found consistent point") are low-level and were previously considered too verbose for LOG. However, based on discussion, some users still find it useful to see these messages at LOG level for debugging. Therefore, with the default setting (DEBUG1), these messages are logged at LOG level. On the other hand, setting trace_logical_decoding_messages to LOG can suppress them. --- doc/src/sgml/config.sgml | 25 ++++++++++++++++++++ src/backend/replication/logical/logical.c | 2 +- src/backend/replication/logical/logicalctl.c | 24 +++++++++++++++++++ src/backend/replication/logical/snapbuild.c | 8 +++---- src/backend/utils/misc/guc_parameters.dat | 11 +++++++++ src/backend/utils/misc/guc_tables.c | 1 + src/include/replication/logicalctl.h | 3 +++ 7 files changed, 69 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 8cdd826fbd3..b48a80c5508 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -12595,6 +12595,31 @@ dynamic_library_path = '/usr/local/lib/postgresql:$libdir' + + trace_logical_decoding_messages (enum) + + trace_logical_decoding_messages configuration parameter + + + + + Enables logging of logical decoding-related debugging output that + otherwise would not be logged. This parameter allows the user to + override the normal setting of , + but only for specific messages. This is intended for use in debugging + logical decoding. Valid values are DEBUG5, + DEBUG4, DEBUG3, + DEBUG2, DEBUG1, and + LOG. The setting values cause logical + decoding-related debug messages of that priority or higher to be logged + as though they had LOG priority; for common settings + of log_min_messages this results in unconditionally + sending them to the server log. + The default is DEBUG1. + + + + trace_notify (boolean) diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c index f20d0c542f3..7d3c0da70f6 100644 --- a/src/backend/replication/logical/logical.c +++ b/src/backend/replication/logical/logical.c @@ -598,7 +598,7 @@ CreateDecodingContext(XLogRecPtr start_lsn, ctx->reorder->output_rewrites = ctx->options.receive_rewrites; - ereport(DEBUG1, + ereport(trace_logical_decoding(DEBUG1), (errmsg("starting logical decoding for slot \"%s\"", NameStr(slot->data.name)), errdetail("Streaming transactions committing after %X/%08X, reading WAL from %X/%08X.", diff --git a/src/backend/replication/logical/logicalctl.c b/src/backend/replication/logical/logicalctl.c index 4e292951201..d735a63d828 100644 --- a/src/backend/replication/logical/logicalctl.c +++ b/src/backend/replication/logical/logicalctl.c @@ -116,6 +116,9 @@ bool XLogLogicalInfo = false; */ static bool XLogLogicalInfoUpdatePending = false; +/* GUC variables */ +int trace_logical_decoding_messages = DEBUG1; + static void update_xlog_logical_info(void); static void abort_logical_decoding_activation(int code, Datum arg); static void write_logical_decoding_status_update_record(bool status); @@ -638,3 +641,24 @@ UpdateLogicalDecodingStatusEndOfRecovery(void) INJECTION_POINT("startup-logical-decoding-status-change-end-of-recovery", NULL); } + +/* + * Adjust the level of a logical decoding-related message per + * trace_logical_decoding_messages. + * + * The argument is the default log level of the message, eg, DEBUG2. (This + * should only be applied to DEBUGn log messages, otherwise it's a no-op.) + * If the level is >= trace_logical_decoding_messages, we return LOG, causing + * the message to be logged unconditionally (for most settings of + * log_min_messages). Otherwise, we return the argument unchanged. + * The message will then be shown based on the setting of log_min_messages. + */ +int +trace_logical_decoding(int trace_level) +{ + if (trace_level < LOG && + trace_level >= trace_logical_decoding_messages) + return LOG; + + return trace_level; +} diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index b4269a3b102..6c878cbcfd0 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -1312,7 +1312,7 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn builder->state = SNAPBUILD_CONSISTENT; builder->next_phase_at = InvalidTransactionId; - ereport(DEBUG1, + ereport(trace_logical_decoding(DEBUG1), errmsg("logical decoding found consistent point at %X/%08X", LSN_FORMAT_ARGS(lsn)), errdetail("There are no running transactions.")); @@ -1385,7 +1385,7 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn builder->state = SNAPBUILD_FULL_SNAPSHOT; builder->next_phase_at = running->nextXid; - ereport(LOG, + ereport(trace_logical_decoding(DEBUG1), errmsg("logical decoding found initial consistent point at %X/%08X", LSN_FORMAT_ARGS(lsn)), errdetail("Waiting for transactions (approximately %d) older than %u to end.", @@ -1409,7 +1409,7 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn builder->state = SNAPBUILD_CONSISTENT; builder->next_phase_at = InvalidTransactionId; - ereport(DEBUG1, + ereport(trace_logical_decoding(DEBUG1), errmsg("logical decoding found consistent point at %X/%08X", LSN_FORMAT_ARGS(lsn)), errdetail("There are no old transactions anymore.")); @@ -1915,7 +1915,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) Assert(builder->state == SNAPBUILD_CONSISTENT); - ereport(DEBUG1, + ereport(trace_logical_decoding(DEBUG1), errmsg("logical decoding found consistent point at %X/%08X", LSN_FORMAT_ARGS(lsn)), errdetail("Logical decoding will begin using saved snapshot.")); diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat index 0c9854ad8fc..04cd0d8c3be 100644 --- a/src/backend/utils/misc/guc_parameters.dat +++ b/src/backend/utils/misc/guc_parameters.dat @@ -3039,6 +3039,17 @@ ifdef => 'LOCK_DEBUG', }, +# client_message_level_options allows too many values, really, but +# it's not worth having a separate options array for this. +{ name => 'trace_logical_decoding_messages', type => 'enum', context => 'PGC_USERSET', group => 'DEVELOPER_OPTIONS', + short_desc => 'Enables logging of logical decoding-related debugging information.', + long_desc => 'Each level includes all the levels that follow it. The later the level, the fewer messages are sent.', + flags => 'GUC_NOT_IN_SAMPLE', + variable => 'trace_logical_decoding_messages', + boot_val => 'DEBUG1', + options => 'client_message_level_options', +}, + { name => 'trace_lwlocks', type => 'bool', context => 'PGC_SUSET', group => 'DEVELOPER_OPTIONS', short_desc => 'Emits information about lightweight lock usage.', flags => 'GUC_NOT_IN_SAMPLE', diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 1e14b7b4af0..8e83021afa3 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -72,6 +72,7 @@ #include "postmaster/syslogger.h" #include "postmaster/walsummarizer.h" #include "postmaster/walwriter.h" +#include "replication/logicalctl.h" #include "replication/logicallauncher.h" #include "replication/slot.h" #include "replication/slotsync.h" diff --git a/src/include/replication/logicalctl.h b/src/include/replication/logicalctl.h index 495554c532c..6b2db5ba273 100644 --- a/src/include/replication/logicalctl.h +++ b/src/include/replication/logicalctl.h @@ -14,6 +14,8 @@ #ifndef LOGICALCTL_H #define LOGICALCTL_H +extern PGDLLIMPORT int trace_logical_decoding_messages; + extern Size LogicalDecodingCtlShmemSize(void); extern void LogicalDecodingCtlShmemInit(void); extern void StartupLogicalDecodingStatus(bool last_status); @@ -28,5 +30,6 @@ extern void RequestDisableLogicalDecoding(void); extern void DisableLogicalDecodingIfNecessary(void); extern void DisableLogicalDecoding(void); extern void UpdateLogicalDecodingStatusEndOfRecovery(void); +extern int trace_logical_decoding(int trace_level); #endif -- 2.51.2