agora inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v4 2/3] Adding XID generation count per backend
556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ 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; 556+ 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] 556+ messages in thread

* [PATCH 5/5] Use BulkInsertState when copying data to the new heap.
@ 2026-03-05 18:58  Antonin Houska <[email protected]>
  0 siblings, 0 replies; 556+ messages in thread

From: Antonin Houska @ 2026-03-05 18:58 UTC (permalink / raw)

It should make the copying more efficient. Besides that, buffer access
strategy is involved this way.

This diff reverts the changes done in previous parts of the series to
reform_and_rewrite_tuple() and introduces a separate function
heap_insert_for_repack().
---
 src/backend/access/heap/heapam_handler.c | 110 +++++++++++++++--------
 1 file changed, 72 insertions(+), 38 deletions(-)

diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index f4c62e5bc7a..50ddee9d8c8 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -49,6 +49,11 @@
 static void reform_and_rewrite_tuple(HeapTuple tuple,
 									 Relation OldHeap, Relation NewHeap,
 									 Datum *values, bool *isnull, RewriteState rwstate);
+static void heap_insert_for_repack(HeapTuple tuple, Relation OldHeap,
+								   Relation NewHeap, Datum *values, bool *isnull,
+								   BulkInsertState bistate);
+static HeapTuple reform_tuple(HeapTuple tuple, Relation OldHeap,
+							  Relation NewHeap, Datum *values, bool *isnull);
 
 static bool SampleHeapTupleVisible(TableScanDesc scan, Buffer buffer,
 								   HeapTuple tuple,
@@ -694,6 +699,7 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
 								 double *tups_recently_dead)
 {
 	RewriteState rwstate = NULL;
+	BulkInsertState	bistate = NULL;
 	IndexScanDesc indexScan;
 	TableScanDesc tableScan;
 	HeapScanDesc heapScan;
@@ -729,6 +735,8 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
 	if (!concurrent)
 		rwstate = begin_heap_rewrite(OldHeap, NewHeap, OldestXmin,
 									 *xid_cutoff, *multi_cutoff);
+	else
+		bistate = GetBulkInsertState();
 
 
 	/* Set up sorting if wanted */
@@ -958,8 +966,12 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
 			};
 			int64		ct_val[2];
 
-			reform_and_rewrite_tuple(tuple, OldHeap, NewHeap,
-									 values, isnull, rwstate);
+			if (!concurrent)
+				reform_and_rewrite_tuple(tuple, OldHeap, NewHeap,
+										 values, isnull, rwstate);
+			else
+				heap_insert_for_repack(tuple, OldHeap, NewHeap,
+									   values, isnull, bistate);
 
 			/*
 			 * In indexscan mode and also VACUUM FULL, report increase in
@@ -1007,10 +1019,15 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
 				break;
 
 			n_tuples += 1;
-			reform_and_rewrite_tuple(tuple,
-									 OldHeap, NewHeap,
-									 values, isnull,
-									 rwstate);
+			if (!concurrent)
+				reform_and_rewrite_tuple(tuple,
+										 OldHeap, NewHeap,
+										 values, isnull,
+										 rwstate);
+			else
+				heap_insert_for_repack(tuple, OldHeap, NewHeap,
+									   values, isnull, bistate);
+
 			/* Report n_tuples */
 			pgstat_progress_update_param(PROGRESS_REPACK_HEAP_TUPLES_INSERTED,
 										 n_tuples);
@@ -1022,6 +1039,8 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
 	/* Write out any remaining tuples, and fsync if needed */
 	if (rwstate)
 		end_heap_rewrite(rwstate);
+	if (bistate)
+		FreeBulkInsertState(bistate);
 
 	/* Clean up */
 	pfree(values);
@@ -2414,56 +2433,71 @@ heapam_scan_sample_next_tuple(TableScanDesc scan, SampleScanState *scanstate,
  * SET WITHOUT OIDS.
  *
  * So, we must reconstruct the tuple from component Datums.
- *
- * If rwstate=NULL, use simple_heap_insert() instead of rewriting - in that
- * case we still need to deform/form the tuple. TODO Shouldn't we rename the
- * function, as might not do any rewrite?
  */
 static void
 reform_and_rewrite_tuple(HeapTuple tuple,
 						 Relation OldHeap, Relation NewHeap,
 						 Datum *values, bool *isnull, RewriteState rwstate)
+{
+	HeapTuple       copiedTuple;
+
+	copiedTuple = reform_tuple(tuple, OldHeap, NewHeap, values, isnull);
+
+	/* The heap rewrite module does the rest */
+	rewrite_heap_tuple(rwstate, tuple, copiedTuple);
+
+	heap_freetuple(copiedTuple);
+}
+
+/*
+ * Insert tuple when processing REPACK CONCURRENTLY.
+ *
+ * rewriteheap.c is not used in the CONCURRENTLY case because it'd be
+ * difficult to do the same in the catch-up phase (as the logical
+ * decoding does not provide us with sufficient visibility
+ * information). Thus we must use heap_insert() both during the
+ * catch-up and here.
+ *
+ * We pass the NO_LOGICAL flag to heap_insert() in order to skip logical
+ * decoding: as soon as REPACK CONCURRENTLY swaps the relation files, it drops
+ * this relation, so no logical replication subscription should need the data.
+ *
+ * BulkInsertState is used because many tuples are inserted in the typical
+ * case.
+ */
+static void
+heap_insert_for_repack(HeapTuple tuple, Relation OldHeap, Relation NewHeap,
+					   Datum *values, bool *isnull, BulkInsertState bistate)
+{
+	tuple = reform_tuple(tuple, OldHeap, NewHeap, values, isnull);
+
+	heap_insert(NewHeap, tuple, GetCurrentCommandId(true),
+				HEAP_INSERT_NO_LOGICAL, bistate);
+
+	heap_freetuple(tuple);
+}
+
+/*
+ * Deform tuple, set values of dropped columns to NULL, form a new tuple and
+ * return it.
+ */
+static HeapTuple
+reform_tuple(HeapTuple tuple, Relation OldHeap, Relation NewHeap,
+			 Datum *values, bool *isnull)
 {
 	TupleDesc	oldTupDesc = RelationGetDescr(OldHeap);
 	TupleDesc	newTupDesc = RelationGetDescr(NewHeap);
-	HeapTuple	copiedTuple;
 	int			i;
 
 	heap_deform_tuple(tuple, oldTupDesc, values, isnull);
 
-	/* Be sure to null out any dropped columns */
 	for (i = 0; i < newTupDesc->natts; i++)
 	{
 		if (TupleDescCompactAttr(newTupDesc, i)->attisdropped)
 			isnull[i] = true;
 	}
 
-	copiedTuple = heap_form_tuple(newTupDesc, values, isnull);
-
-	if (rwstate)
-		/* The heap rewrite module does the rest */
-		rewrite_heap_tuple(rwstate, tuple, copiedTuple);
-	else
-	{
-		/*
-		 * Insert tuple when processing REPACK CONCURRENTLY.
-		 *
-		 * rewriteheap.c is not used in the CONCURRENTLY case because it'd be
-		 * difficult to do the same in the catch-up phase (as the logical
-		 * decoding does not provide us with sufficient visibility
-		 * information). Thus we must use heap_insert() both during the
-		 * catch-up and here.
-		 *
-		 * The following is like simple_heap_insert() except that we pass the
-		 * flag to skip logical decoding: as soon as REPACK CONCURRENTLY swaps
-		 * the relation files, it drops this relation, so no logical
-		 * replication subscription should need the data.
-		 */
-		heap_insert(NewHeap, copiedTuple, GetCurrentCommandId(true),
-					HEAP_INSERT_NO_LOGICAL, NULL);
-	}
-
-	heap_freetuple(copiedTuple);
+	return heap_form_tuple(newTupDesc, values, isnull);
 }
 
 /*
-- 
2.47.3


--=-=-=--





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


end of thread, other threads:[~2026-03-05 18:58 UTC | newest]

Thread overview: 556+ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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-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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2026-03-05 18:58 [PATCH 5/5] Use BulkInsertState when copying data to the new heap. Antonin Houska <[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