pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Fujii Masao <masao.fujii@oss.nttdata.com>
To: Nisha Moond <nisha.moond412@gmail.com>
To: Gunnar Morling <gunnar.morling@googlemail.com>
Cc: pgsql-bugs@lists.postgresql.org
Subject: Re: Unexpected behavior when setting "idle_replication_slot_timeout"
Date: Sat, 5 Jul 2025 00:22:26 +0900
Message-ID: <b26f13d7-769a-4b64-8bed-cb3a833c0604@oss.nttdata.com> (raw)
In-Reply-To: <30e91649-06dd-453e-8658-5f4acd03a3bd@oss.nttdata.com>
References: <CADGJaX_0+FTguWpNSpgVWYQP_7MhoO0D8=cp4XozSQgaZ40Odw@mail.gmail.com>
	<CABdArM76e8-XChodqKxEiRK3tR_Yv3cymn_AWfP4bOsLDscZAg@mail.gmail.com>
	<30e91649-06dd-453e-8658-5f4acd03a3bd@oss.nttdata.com>



On 2025/07/04 23:12, Fujii Masao wrote:
> But I wonder why the current unit of this GUC is minutes (GUC_UNIT_MIN).
> Since at least two users (including myself) tried to set it to a value
> less than 1 minute, it might worth considering changing the unit to seconds
> (GUC_UNIT_S). Also which would reduces the chance of the reported trouble.

Attached patch changes unit of idle_replication_slot_timeout to seconds.

Regards,

-- 
Fujii Masao
NTT DATA Japan Corporation
From d7e528c1adaf517b86ef97454c80d369f7c9f23a Mon Sep 17 00:00:00 2001
From: Fujii Masao <fujii@postgresql.org>
Date: Fri, 4 Jul 2025 23:39:48 +0900
Subject: [PATCH v1] Change unit of idle_replication_slot_timeout to seconds.

Previously, idle_replication_slot_timeout was measured in minutes.
This commit changes the unit to seconds, allowing finer-grained
timeout settings.
---
 doc/src/sgml/config.sgml                      |  2 +-
 src/backend/replication/slot.c                | 15 ++++++---------
 src/backend/utils/misc/guc_tables.c           |  6 +++---
 src/backend/utils/misc/postgresql.conf.sample |  2 +-
 src/include/replication/slot.h                |  2 +-
 5 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 59a0874528a..bd12225cbe4 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -4620,7 +4620,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
        <para>
         Invalidate replication slots that have remained idle longer than this
         duration. If this value is specified without units, it is taken as
-        minutes. A value of zero (the default) disables the idle timeout
+        seconds. A value of zero (the default) disables the idle timeout
         invalidation mechanism. This parameter can only be set in the
         <filename>postgresql.conf</filename> file or on the server command
         line.
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index f9fec50ae88..a6512034ba7 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -154,7 +154,7 @@ int			max_replication_slots = 10; /* the maximum number of replication
  * Invalidate replication slots that have remained idle longer than this
  * duration; '0' disables it.
  */
-int			idle_replication_slot_timeout_mins = 0;
+int			idle_replication_slot_timeout_secs = 0;
 
 /*
  * This GUC lists streaming replication standby server slot names that
@@ -1612,13 +1612,10 @@ ReportSlotInvalidation(ReplicationSlotInvalidationCause cause,
 
 		case RS_INVAL_IDLE_TIMEOUT:
 			{
-				int			minutes = slot_idle_seconds / SECS_PER_MINUTE;
-				int			secs = slot_idle_seconds % SECS_PER_MINUTE;
-
 				/* translator: %s is a GUC variable name */
-				appendStringInfo(&err_detail, _("The slot's idle time of %dmin %02ds exceeds the configured \"%s\" duration of %dmin."),
-								 minutes, secs, "idle_replication_slot_timeout",
-								 idle_replication_slot_timeout_mins);
+				appendStringInfo(&err_detail, _("The slot's idle time of %lds exceeds the configured \"%s\" duration of %ds."),
+								 slot_idle_seconds, "idle_replication_slot_timeout",
+								 idle_replication_slot_timeout_secs);
 				/* translator: %s is a GUC variable name */
 				appendStringInfo(&err_hint, _("You might need to increase \"%s\"."),
 								 "idle_replication_slot_timeout");
@@ -1656,7 +1653,7 @@ ReportSlotInvalidation(ReplicationSlotInvalidationCause cause,
 static inline bool
 CanInvalidateIdleSlot(ReplicationSlot *s)
 {
-	return (idle_replication_slot_timeout_mins != 0 &&
+	return (idle_replication_slot_timeout_secs != 0 &&
 			!XLogRecPtrIsInvalid(s->data.restart_lsn) &&
 			s->inactive_since > 0 &&
 			!(RecoveryInProgress() && s->data.synced));
@@ -1734,7 +1731,7 @@ DetermineSlotInvalidationCause(uint32 possible_causes, ReplicationSlot *s,
 			 * idle_replication_slot_timeout GUC.
 			 */
 			if (TimestampDifferenceExceedsSeconds(s->inactive_since, now,
-												  idle_replication_slot_timeout_mins * SECS_PER_MINUTE))
+												  idle_replication_slot_timeout_secs))
 			{
 				*inactive_since = s->inactive_since;
 				return RS_INVAL_IDLE_TIMEOUT;
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 511dc32d519..a925be86944 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -3100,10 +3100,10 @@ struct config_int ConfigureNamesInt[] =
 			gettext_noop("Sets the duration a replication slot can remain idle before "
 						 "it is invalidated."),
 			NULL,
-			GUC_UNIT_MIN
+			GUC_UNIT_S
 		},
-		&idle_replication_slot_timeout_mins,
-		0, 0, INT_MAX / SECS_PER_MINUTE,
+		&idle_replication_slot_timeout_secs,
+		0, 0, INT_MAX,
 		check_idle_replication_slot_timeout, NULL, NULL
 	},
 
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 341f88adc87..a9d8293474a 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -342,7 +342,7 @@
 				# (change requires restart)
 #wal_keep_size = 0		# in megabytes; 0 disables
 #max_slot_wal_keep_size = -1	# in megabytes; -1 disables
-#idle_replication_slot_timeout = 0	# in minutes; 0 disables
+#idle_replication_slot_timeout = 0	# in seconds; 0 disables
 #wal_sender_timeout = 60s	# in milliseconds; 0 disables
 #track_commit_timestamp = off	# collect timestamp of transaction commit
 				# (change requires restart)
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index ffacba9d2ae..76aeeb92242 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -266,7 +266,7 @@ extern PGDLLIMPORT ReplicationSlot *MyReplicationSlot;
 /* GUCs */
 extern PGDLLIMPORT int max_replication_slots;
 extern PGDLLIMPORT char *synchronized_standby_slots;
-extern PGDLLIMPORT int idle_replication_slot_timeout_mins;
+extern PGDLLIMPORT int idle_replication_slot_timeout_secs;
 
 /* shmem initialization functions */
 extern Size ReplicationSlotsShmemSize(void);
-- 
2.49.0



Attachments:

  [text/plain] v1-0001-Change-unit-of-idle_replication_slot_timeout-to-s.patch (5.5K, ../b26f13d7-769a-4b64-8bed-cb3a833c0604@oss.nttdata.com/2-v1-0001-Change-unit-of-idle_replication_slot_timeout-to-s.patch)
  download | inline diff:
From d7e528c1adaf517b86ef97454c80d369f7c9f23a Mon Sep 17 00:00:00 2001
From: Fujii Masao <fujii@postgresql.org>
Date: Fri, 4 Jul 2025 23:39:48 +0900
Subject: [PATCH v1] Change unit of idle_replication_slot_timeout to seconds.

Previously, idle_replication_slot_timeout was measured in minutes.
This commit changes the unit to seconds, allowing finer-grained
timeout settings.
---
 doc/src/sgml/config.sgml                      |  2 +-
 src/backend/replication/slot.c                | 15 ++++++---------
 src/backend/utils/misc/guc_tables.c           |  6 +++---
 src/backend/utils/misc/postgresql.conf.sample |  2 +-
 src/include/replication/slot.h                |  2 +-
 5 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 59a0874528a..bd12225cbe4 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -4620,7 +4620,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
        <para>
         Invalidate replication slots that have remained idle longer than this
         duration. If this value is specified without units, it is taken as
-        minutes. A value of zero (the default) disables the idle timeout
+        seconds. A value of zero (the default) disables the idle timeout
         invalidation mechanism. This parameter can only be set in the
         <filename>postgresql.conf</filename> file or on the server command
         line.
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index f9fec50ae88..a6512034ba7 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -154,7 +154,7 @@ int			max_replication_slots = 10; /* the maximum number of replication
  * Invalidate replication slots that have remained idle longer than this
  * duration; '0' disables it.
  */
-int			idle_replication_slot_timeout_mins = 0;
+int			idle_replication_slot_timeout_secs = 0;
 
 /*
  * This GUC lists streaming replication standby server slot names that
@@ -1612,13 +1612,10 @@ ReportSlotInvalidation(ReplicationSlotInvalidationCause cause,
 
 		case RS_INVAL_IDLE_TIMEOUT:
 			{
-				int			minutes = slot_idle_seconds / SECS_PER_MINUTE;
-				int			secs = slot_idle_seconds % SECS_PER_MINUTE;
-
 				/* translator: %s is a GUC variable name */
-				appendStringInfo(&err_detail, _("The slot's idle time of %dmin %02ds exceeds the configured \"%s\" duration of %dmin."),
-								 minutes, secs, "idle_replication_slot_timeout",
-								 idle_replication_slot_timeout_mins);
+				appendStringInfo(&err_detail, _("The slot's idle time of %lds exceeds the configured \"%s\" duration of %ds."),
+								 slot_idle_seconds, "idle_replication_slot_timeout",
+								 idle_replication_slot_timeout_secs);
 				/* translator: %s is a GUC variable name */
 				appendStringInfo(&err_hint, _("You might need to increase \"%s\"."),
 								 "idle_replication_slot_timeout");
@@ -1656,7 +1653,7 @@ ReportSlotInvalidation(ReplicationSlotInvalidationCause cause,
 static inline bool
 CanInvalidateIdleSlot(ReplicationSlot *s)
 {
-	return (idle_replication_slot_timeout_mins != 0 &&
+	return (idle_replication_slot_timeout_secs != 0 &&
 			!XLogRecPtrIsInvalid(s->data.restart_lsn) &&
 			s->inactive_since > 0 &&
 			!(RecoveryInProgress() && s->data.synced));
@@ -1734,7 +1731,7 @@ DetermineSlotInvalidationCause(uint32 possible_causes, ReplicationSlot *s,
 			 * idle_replication_slot_timeout GUC.
 			 */
 			if (TimestampDifferenceExceedsSeconds(s->inactive_since, now,
-												  idle_replication_slot_timeout_mins * SECS_PER_MINUTE))
+												  idle_replication_slot_timeout_secs))
 			{
 				*inactive_since = s->inactive_since;
 				return RS_INVAL_IDLE_TIMEOUT;
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 511dc32d519..a925be86944 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -3100,10 +3100,10 @@ struct config_int ConfigureNamesInt[] =
 			gettext_noop("Sets the duration a replication slot can remain idle before "
 						 "it is invalidated."),
 			NULL,
-			GUC_UNIT_MIN
+			GUC_UNIT_S
 		},
-		&idle_replication_slot_timeout_mins,
-		0, 0, INT_MAX / SECS_PER_MINUTE,
+		&idle_replication_slot_timeout_secs,
+		0, 0, INT_MAX,
 		check_idle_replication_slot_timeout, NULL, NULL
 	},
 
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 341f88adc87..a9d8293474a 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -342,7 +342,7 @@
 				# (change requires restart)
 #wal_keep_size = 0		# in megabytes; 0 disables
 #max_slot_wal_keep_size = -1	# in megabytes; -1 disables
-#idle_replication_slot_timeout = 0	# in minutes; 0 disables
+#idle_replication_slot_timeout = 0	# in seconds; 0 disables
 #wal_sender_timeout = 60s	# in milliseconds; 0 disables
 #track_commit_timestamp = off	# collect timestamp of transaction commit
 				# (change requires restart)
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index ffacba9d2ae..76aeeb92242 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -266,7 +266,7 @@ extern PGDLLIMPORT ReplicationSlot *MyReplicationSlot;
 /* GUCs */
 extern PGDLLIMPORT int max_replication_slots;
 extern PGDLLIMPORT char *synchronized_standby_slots;
-extern PGDLLIMPORT int idle_replication_slot_timeout_mins;
+extern PGDLLIMPORT int idle_replication_slot_timeout_secs;
 
 /* shmem initialization functions */
 extern Size ReplicationSlotsShmemSize(void);
-- 
2.49.0



view thread (38+ messages)  latest in thread

Message-ID: <b26f13d7-769a-4b64-8bed-cb3a833c0604@oss.nttdata.com>
Permalink:  ../b26f13d7-769a-4b64-8bed-cb3a833c0604@oss.nttdata.com/
Also on:    postgresql.org/message-id/b26f13d7-769a-4b64-8bed-cb3a833c0604@oss.nttdata.com

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-bugs@postgresql.org
  Cc: masao.fujii@oss.nttdata.com, nisha.moond412@gmail.com, gunnar.morling@googlemail.com, pgsql-bugs@lists.postgresql.org
  Subject: Re: Unexpected behavior when setting "idle_replication_slot_timeout"
  In-Reply-To: <b26f13d7-769a-4b64-8bed-cb3a833c0604@oss.nttdata.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox