agora inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v4 2/3] Adding XID generation count per backend
199+ messages / 2 participants
[nested] [flat]

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v4 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c9..72c8aa7650b 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 47ce61e5093..5e509153656 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -285,9 +285,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0fdbaf79780..d78633cae44 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -510,6 +511,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--jg9kqX3osLGO+8A7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v4-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v5 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/backend/utils/activity/
  19.4% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 1441a051773..fe625d00f7d 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -24,6 +24,7 @@
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "utils/lsyscache.h"
+#include "utils/pgstat_internal.h"
 #include "utils/syscache.h"
 
 
@@ -261,6 +262,9 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		PendingBackendStats.pending_xid_count++;
+		backend_has_xactstats = true;
+		pgstat_report_fixed = true;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 42bfb9cd38f..32ee48eab51 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -287,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	PendingBackendStats.pending_xid_count = 0;
 
 	backend_has_xactstats = false;
 }
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5d73c4dfbcf..780ca4b3ac0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -525,6 +525,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -543,6 +544,7 @@ typedef struct PgStat_BackendPending
 	 */
 	PgStat_Counter pending_xact_commit;
 	PgStat_Counter pending_xact_rollback;
+	PgStat_Counter pending_xid_count;
 } PgStat_BackendPending;
 
 /*
-- 
2.34.1


--uN5gGi2rtCNSVbpC
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v5-0003-Adding-the-pg_stat_backend_transaction-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v3 2/3] Adding XID generation count per backend
@ 2025-08-08 15:58  Bertrand Drouvot <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.

The counter is not part of PgStat_BackendPending, because we want to avoid
an extra function call in this code path to increment the counter in
PendingBackendStats. The counter increment here behaves more or less the same as
we do for WAL statistics.
---
 src/backend/access/transam/varsup.c         | 2 ++
 src/backend/utils/activity/pgstat_backend.c | 6 +++++-
 src/include/pgstat.h                        | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
  10.1% src/backend/access/transam/
  69.3% src/backend/utils/activity/
  20.5% src/include/

diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fe895787cb7..26c72cbe091 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -21,6 +21,7 @@
 #include "access/xlogutils.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
@@ -257,6 +258,7 @@ GetNewTransactionId(bool isSubXact)
 		/* LWLockRelease acts as barrier */
 		MyProc->xid = xid;
 		ProcGlobal->xids[MyProc->pgxactoff] = xid;
+		XidGenCount++;
 	}
 	else
 	{
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bf164854c4b..8b530c510b9 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -52,6 +52,8 @@ static WalUsage prevBackendWalUsage;
  */
 static bool backend_has_xactstats = false;
 
+PgStat_Counter XidGenCount = 0;
+
 /*
  * Utility routines to report I/O stats for backends, kept here to avoid
  * exposing PendingBackendStats to the outside world.
@@ -285,9 +287,11 @@ pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
 
 	shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
 	shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
+	shbackendent->stats.xid_count += XidGenCount;
 
 	PendingBackendStats.pending_xact_commit = 0;
 	PendingBackendStats.pending_xact_rollback = 0;
+	XidGenCount = 0;
 
 	backend_has_xactstats = false;
 }
@@ -317,7 +321,7 @@ pgstat_flush_backend(bool nowait, bits32 flags)
 		has_pending_data = true;
 
 	/* Some transaction data pending? */
-	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
+	if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && (backend_has_xactstats || XidGenCount > 0))
 		has_pending_data = true;
 
 	if (!has_pending_data)
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9efc0e10ebf..94dd24b3eac 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -492,6 +492,7 @@ typedef struct PgStat_Backend
 	PgStat_WalCounters wal_counters;
 	PgStat_Counter xact_commit;
 	PgStat_Counter xact_rollback;
+	PgStat_Counter xid_count;
 } PgStat_Backend;
 
 /* ---------
@@ -571,6 +572,8 @@ extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);
 
+extern PGDLLIMPORT PgStat_Counter XidGenCount;
+
 /*
  * Functions in pgstat_bgwriter.c
  */
-- 
2.34.1


--u6+Li7FU79Mt/lVd
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="v3-0003-Adding-the-pg_stat_backend-view.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread

* [PATCH v1 3/4] Add alias to be used as "unset" state.
@ 2025-08-30 19:34  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 199+ messages in thread

From: Nikolay Shaplov @ 2025-08-30 19:34 UTC (permalink / raw)

Add `unset_alias` string parameter to trenary reloption definition. This will allow
user explicitly switch trenary option to "unset" state. Use this feature to
implement `vacuum_index_cleanup` and gist's `buffering` reloptions as trenary
reloptions
---
 src/backend/access/common/reloptions.c | 91 +++++++++++---------------
 src/backend/access/gist/gistbuild.c    |  4 +-
 src/backend/commands/vacuum.c          | 11 ++--
 src/include/access/gist_private.h      | 10 +--
 src/include/access/reloptions.h        |  7 +-
 src/include/utils/rel.h                | 10 +--
 src/test/regress/expected/gist.out     |  3 +-
 7 files changed, 54 insertions(+), 82 deletions(-)

diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 24662d277c8..a96abcb056c 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -170,6 +170,27 @@ static relopt_trenary trenaryRelOpts[] =
 			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
 			ShareUpdateExclusiveLock
 		},
+		NULL,
+		TRENARY_UNSET
+	},
+	{
+		{
+			"vacuum_index_cleanup",
+			"Controls index vacuuming and index cleanup",
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			ShareUpdateExclusiveLock
+		},
+		"auto",
+		TRENARY_UNSET
+	},
+	{
+		{
+			"buffering",
+			"Enables buffering build for this GiST index",
+			RELOPT_KIND_GIST,
+			AccessExclusiveLock
+		},
+		"auto",
 		TRENARY_UNSET
 	},
 	/* list terminator */
@@ -489,30 +510,6 @@ static relopt_real realRelOpts[] =
 	{{NULL}}
 };
 
-/* values from StdRdOptIndexCleanup */
-static relopt_enum_elt_def StdRdOptIndexCleanupValues[] =
-{
-	{"auto", STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO},
-	{"on", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON},
-	{"off", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF},
-	{"true", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON},
-	{"false", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF},
-	{"yes", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON},
-	{"no", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF},
-	{"1", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON},
-	{"0", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF},
-	{(const char *) NULL}		/* list terminator */
-};
-
-/* values from GistOptBufferingMode */
-static relopt_enum_elt_def gistBufferingOptValues[] =
-{
-	{"auto", GIST_OPTION_BUFFERING_AUTO},
-	{"on", GIST_OPTION_BUFFERING_ON},
-	{"off", GIST_OPTION_BUFFERING_OFF},
-	{(const char *) NULL}		/* list terminator */
-};
-
 /* values from ViewOptCheckOption */
 static relopt_enum_elt_def viewCheckOptValues[] =
 {
@@ -524,28 +521,6 @@ static relopt_enum_elt_def viewCheckOptValues[] =
 
 static relopt_enum enumRelOpts[] =
 {
-	{
-		{
-			"vacuum_index_cleanup",
-			"Controls index vacuuming and index cleanup",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-			ShareUpdateExclusiveLock
-		},
-		StdRdOptIndexCleanupValues,
-		STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO,
-		gettext_noop("Valid values are \"on\", \"off\", and \"auto\".")
-	},
-	{
-		{
-			"buffering",
-			"Enables buffering build for this GiST index",
-			RELOPT_KIND_GIST,
-			AccessExclusiveLock
-		},
-		gistBufferingOptValues,
-		GIST_OPTION_BUFFERING_AUTO,
-		gettext_noop("Valid values are \"on\", \"off\", and \"auto\".")
-	},
 	{
 		{
 			"check_option",
@@ -913,13 +888,14 @@ add_local_bool_reloption(local_relopts *relopts, const char *name,
  */
 static relopt_trenary *
 init_trenary_reloption(bits32 kinds, const char *name, const char *desc,
-					trenary default_val, LOCKMODE lockmode)
+			trenary default_val, const char* unset_alias, LOCKMODE lockmode)
 {
 	relopt_trenary *newoption;
 
 	newoption = (relopt_trenary *) allocate_reloption(kinds,
 									RELOPT_TYPE_TRENARY, name, desc, lockmode);
 	newoption->default_val = default_val;
+	newoption->unset_alias = unset_alias;
 
 	return newoption;
 }
@@ -930,10 +906,10 @@ init_trenary_reloption(bits32 kinds, const char *name, const char *desc,
  */
 void
 add_trenary_reloption(bits32 kinds, const char *name, const char *desc,
-				   trenary default_val, LOCKMODE lockmode)
+			trenary default_val, const char* unset_alias, LOCKMODE lockmode)
 {
 	relopt_trenary *newoption = init_trenary_reloption(kinds, name, desc,
-												 default_val, lockmode);
+											default_val, unset_alias, lockmode);
 
 	add_reloption((relopt_gen *) newoption);
 }
@@ -947,11 +923,11 @@ add_trenary_reloption(bits32 kinds, const char *name, const char *desc,
 void
 add_local_trenary_reloption(local_relopts *relopts, const char *name,
 							const char *desc, trenary default_val,
-							int offset)
+							const char* unset_alias, int offset)
 {
 	relopt_trenary *newoption = init_trenary_reloption(RELOPT_KIND_LOCAL,
 												name, desc,
-												default_val, 0);
+												default_val, unset_alias, 0);
 
 	add_local_reloption(relopts, (relopt_gen *) newoption, offset);
 }
@@ -1692,8 +1668,19 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
 		case RELOPT_TYPE_TRENARY:
 			{
 				bool b;
+				relopt_trenary *opt = (relopt_trenary *) option->gen;
+
 				parsed = parse_bool(value, &b);
 				option->values.trenary_val = b ? TRENARY_TRUE : TRENARY_FALSE;
+
+				if (!parsed && opt->unset_alias)
+				{
+					if (pg_strcasecmp(value, opt->unset_alias) == 0)
+					{
+						option->values.trenary_val = TRENARY_UNSET;
+						parsed = true;
+					}
+				}
 				if (validate && !parsed)
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -1988,7 +1975,7 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
 		offsetof(StdRdOptions, user_catalog_table)},
 		{"parallel_workers", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, parallel_workers)},
-		{"vacuum_index_cleanup", RELOPT_TYPE_ENUM,
+		{"vacuum_index_cleanup", RELOPT_TYPE_TRENARY,
 		offsetof(StdRdOptions, vacuum_index_cleanup)},
 		{"vacuum_truncate", RELOPT_TYPE_TRENARY,
 		offsetof(StdRdOptions, vacuum_truncate)},
diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c
index 9b2ec9815f1..bff76dd859e 100644
--- a/src/backend/access/gist/gistbuild.c
+++ b/src/backend/access/gist/gistbuild.c
@@ -213,9 +213,9 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
 	 */
 	if (options)
 	{
-		if (options->buffering_mode == GIST_OPTION_BUFFERING_ON)
+		if (options->buffering_mode == TRENARY_TRUE)
 			buildstate.buildMode = GIST_BUFFERING_STATS;
-		else if (options->buffering_mode == GIST_OPTION_BUFFERING_OFF)
+		else if (options->buffering_mode == TRENARY_FALSE)
 			buildstate.buildMode = GIST_BUFFERING_DISABLED;
 		else					/* must be "auto" */
 			buildstate.buildMode = GIST_BUFFERING_AUTO;
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 7b96c7f9a80..779a6078ccb 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -2175,22 +2175,21 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params,
 	 */
 	if (params.index_cleanup == VACOPTVALUE_UNSPECIFIED)
 	{
-		StdRdOptIndexCleanup vacuum_index_cleanup;
+		trenary vacuum_index_cleanup;
 
 		if (rel->rd_options == NULL)
-			vacuum_index_cleanup = STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO;
+			vacuum_index_cleanup = TRENARY_UNSET;
 		else
 			vacuum_index_cleanup =
 				((StdRdOptions *) rel->rd_options)->vacuum_index_cleanup;
 
-		if (vacuum_index_cleanup == STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO)
+		if (vacuum_index_cleanup == TRENARY_UNSET)
 			params.index_cleanup = VACOPTVALUE_AUTO;
-		else if (vacuum_index_cleanup == STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON)
+		else if (vacuum_index_cleanup == TRENARY_TRUE)
 			params.index_cleanup = VACOPTVALUE_ENABLED;
 		else
 		{
-			Assert(vacuum_index_cleanup ==
-				   STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF);
+			Assert(vacuum_index_cleanup == TRENARY_FALSE);
 			params.index_cleanup = VACOPTVALUE_DISABLED;
 		}
 	}
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index 39404ec7cdb..527c19b6fdf 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -380,14 +380,6 @@ typedef struct GISTBuildBuffers
 	int			rootlevel;
 } GISTBuildBuffers;
 
-/* GiSTOptions->buffering_mode values */
-typedef enum GistOptBufferingMode
-{
-	GIST_OPTION_BUFFERING_AUTO,
-	GIST_OPTION_BUFFERING_ON,
-	GIST_OPTION_BUFFERING_OFF,
-} GistOptBufferingMode;
-
 /*
  * Storage type for GiST's reloptions
  */
@@ -395,7 +387,7 @@ typedef struct GiSTOptions
 {
 	int32		vl_len_;		/* varlena header (do not touch directly!) */
 	int			fillfactor;		/* page fill factor in percent (0..100) */
-	GistOptBufferingMode buffering_mode;	/* buffering build mode */
+	trenary		buffering_mode;	/* buffering build mode */
 } GiSTOptions;
 
 /* gist.c */
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 1a6717ed213..5c8eb9e97f9 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -99,6 +99,7 @@ typedef struct relopt_bool
 typedef struct relopt_rernary
 {
 	relopt_gen	gen;
+	const char	*unset_alias; /* word that will be treaed as unset value */
 	int 		default_val;
 } relopt_trenary;
 
@@ -191,7 +192,8 @@ extern relopt_kind add_reloption_kind(void);
 extern void add_bool_reloption(bits32 kinds, const char *name, const char *desc,
 							   bool default_val, LOCKMODE lockmode);
 extern void add_trenary_reloption(bits32 kinds, const char *name,
-					const char *desc, int default_val, LOCKMODE lockmode);
+					const char *desc, trenary default_val,
+					const char* unset_alias, LOCKMODE lockmode);
 extern void add_int_reloption(bits32 kinds, const char *name, const char *desc,
 							  int default_val, int min_val, int max_val,
 							  LOCKMODE lockmode);
@@ -213,7 +215,8 @@ extern void add_local_bool_reloption(local_relopts *relopts, const char *name,
 									 int offset);
 extern void add_local_trenary_reloption(local_relopts *relopts,
 								const char *name, const char *desc,
-								trenary default_val, int offset);
+								trenary default_val, const char* unset_alias,
+								int offset);
 extern void add_local_int_reloption(local_relopts *relopts, const char *name,
 									const char *desc, int default_val,
 									int min_val, int max_val, int offset);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 08f93bde007..1a1e818bd93 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -329,14 +329,6 @@ typedef struct AutoVacOpts
 	float8		analyze_scale_factor;
 } AutoVacOpts;
 
-/* StdRdOptions->vacuum_index_cleanup values */
-typedef enum StdRdOptIndexCleanup
-{
-	STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO = 0,
-	STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF,
-	STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON,
-} StdRdOptIndexCleanup;
-
 typedef struct StdRdOptions
 {
 	int32		vl_len_;		/* varlena header (do not touch directly!) */
@@ -345,7 +337,7 @@ typedef struct StdRdOptions
 	AutoVacOpts autovacuum;		/* autovacuum-related options */
 	bool		user_catalog_table; /* use as an additional catalog relation */
 	int			parallel_workers;	/* max number of parallel workers */
-	StdRdOptIndexCleanup vacuum_index_cleanup;	/* controls index vacuuming */
+	trenary		vacuum_index_cleanup; /* controls index vacuuming */
 	trenary		vacuum_truncate;	/* enables vacuum to truncate a relation */
 
 	/*
diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out
index c75bbb23b6e..e7482c0faab 100644
--- a/src/test/regress/expected/gist.out
+++ b/src/test/regress/expected/gist.out
@@ -12,8 +12,7 @@ create index gist_pointidx4 on gist_point_tbl using gist(p) with (buffering = au
 drop index gist_pointidx2, gist_pointidx3, gist_pointidx4;
 -- Make sure bad values are refused
 create index gist_pointidx5 on gist_point_tbl using gist(p) with (buffering = invalid_value);
-ERROR:  invalid value for enum option "buffering": invalid_value
-DETAIL:  Valid values are "on", "off", and "auto".
+ERROR:  invalid value for trenary option "buffering": invalid_value
 create index gist_pointidx5 on gist_point_tbl using gist(p) with (fillfactor=9);
 ERROR:  value 9 out of bounds for option "fillfactor"
 DETAIL:  Valid values are between "10" and "100".
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi
Content-Disposition: attachment; filename="v1-0004-Extra-tests.patch"
Content-Transfer-Encoding: 7Bit
Content-Type: text/x-patch; charset="unicode-2-0-utf-8";
 name="v1-0004-Extra-tests.patch"



^ permalink  raw  reply  [nested|flat] 199+ messages in thread


end of thread, other threads:[~2025-08-30 19:34 UTC | newest]

Thread overview: 199+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-30 19:34 [PATCH v1 3/4] Add alias to be used as "unset" state. Nikolay Shaplov <[email protected]>

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