agora inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH 2/2] Add the "dummy_table_am" test module
808+ messages / 2 participants
[nested] [flat]

* [PATCH 2/2] Add the "dummy_table_am" test module
@ 2025-03-01 19:50  Julien Tachoires <[email protected]>
  0 siblings, 0 replies; 808+ messages in thread

From: Julien Tachoires @ 2025-03-01 19:50 UTC (permalink / raw)

This test module is in charge of testing table AM reloptions. It's
very similar to what we do in dummy_index_am as we have to exercise
the exact same kind of feature.
---
 src/test/modules/Makefile                     |   1 +
 src/test/modules/dummy_table_am/Makefile      |  20 +
 src/test/modules/dummy_table_am/README        |  14 +
 .../dummy_table_am/dummy_table_am--1.0.sql    |  13 +
 .../modules/dummy_table_am/dummy_table_am.c   | 581 ++++++++++++++++++
 .../dummy_table_am/dummy_table_am.control     |   5 +
 .../dummy_table_am/expected/reloptions.out    | 181 ++++++
 src/test/modules/dummy_table_am/meson.build   |  33 +
 .../modules/dummy_table_am/sql/reloptions.sql |  99 +++
 src/test/modules/meson.build                  |   1 +
 10 files changed, 948 insertions(+)
 create mode 100644 src/test/modules/dummy_table_am/Makefile
 create mode 100644 src/test/modules/dummy_table_am/README
 create mode 100644 src/test/modules/dummy_table_am/dummy_table_am--1.0.sql
 create mode 100644 src/test/modules/dummy_table_am/dummy_table_am.c
 create mode 100644 src/test/modules/dummy_table_am/dummy_table_am.control
 create mode 100644 src/test/modules/dummy_table_am/expected/reloptions.out
 create mode 100644 src/test/modules/dummy_table_am/meson.build
 create mode 100644 src/test/modules/dummy_table_am/sql/reloptions.sql

diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile
index 4e4be3fa511..8fe2a2904d6 100644
--- a/src/test/modules/Makefile
+++ b/src/test/modules/Makefile
@@ -9,6 +9,7 @@ SUBDIRS = \
 		  commit_ts \
 		  delay_execution \
 		  dummy_index_am \
+		  dummy_table_am \
 		  dummy_seclabel \
 		  libpq_pipeline \
 		  oauth_validator \
diff --git a/src/test/modules/dummy_table_am/Makefile b/src/test/modules/dummy_table_am/Makefile
new file mode 100644
index 00000000000..94837dff392
--- /dev/null
+++ b/src/test/modules/dummy_table_am/Makefile
@@ -0,0 +1,20 @@
+# src/test/modules/dummy_table_am/Makefile
+
+MODULES = dummy_table_am
+
+EXTENSION = dummy_table_am
+DATA = dummy_table_am--1.0.sql
+PGFILEDESC = "dummy_table_am - table access method template"
+
+REGRESS = reloptions
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/dummy_table_am
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/dummy_table_am/README b/src/test/modules/dummy_table_am/README
new file mode 100644
index 00000000000..50cf08ee3b1
--- /dev/null
+++ b/src/test/modules/dummy_table_am/README
@@ -0,0 +1,14 @@
+Dummy Table AM
+==============
+
+Dummy table AM is a module for testing any facility usable by a table
+access method, whose code is kept a maximum simple.
+
+This includes tests for all relation option types:
+- boolean
+- enum
+- integer
+- real
+- strings (with and without NULL as default)
+
+It also includes tests related to unrecognized options.
diff --git a/src/test/modules/dummy_table_am/dummy_table_am--1.0.sql b/src/test/modules/dummy_table_am/dummy_table_am--1.0.sql
new file mode 100644
index 00000000000..12ad3ad174b
--- /dev/null
+++ b/src/test/modules/dummy_table_am/dummy_table_am--1.0.sql
@@ -0,0 +1,13 @@
+/* src/test/modules/dummy_table_am/dummy_table_am--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION dummy_table_am" to load this file. \quit
+
+CREATE FUNCTION dummy_table_am_handler(internal)
+RETURNS table_am_handler
+AS 'MODULE_PATHNAME'
+LANGUAGE C;
+
+-- Access method
+CREATE ACCESS METHOD dummy_table_am TYPE TABLE HANDLER dummy_table_am_handler;
+COMMENT ON ACCESS METHOD dummy_table_am IS 'Dummy Table Access Method';
diff --git a/src/test/modules/dummy_table_am/dummy_table_am.c b/src/test/modules/dummy_table_am/dummy_table_am.c
new file mode 100644
index 00000000000..bc9beba195a
--- /dev/null
+++ b/src/test/modules/dummy_table_am/dummy_table_am.c
@@ -0,0 +1,581 @@
+/*-------------------------------------------------------------------------
+ *
+ * dummy_table_am.c
+ *		Table AM templae main file
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ *	  src/test/modules/dummy_table_am/dummy_table_am.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "fmgr.h"
+#include "miscadmin.h"
+
+#include "access/hio.h"
+#include "access/relscan.h"
+#include "access/reloptions.h"
+#include "access/tableam.h"
+#include "access/sdir.h"
+#include "access/skey.h"
+#include "executor/tuptable.h"
+#include "utils/relcache.h"
+#include "utils/snapshot.h"
+
+
+PG_MODULE_MAGIC;
+
+/* Base structures for scans */
+typedef struct DummyScanDescData
+{
+	TableScanDescData rs_base;	/* AM independent part of the descriptor */
+
+	/* Add more fields here as needed by the AM. */
+}			DummyScanDescData;
+typedef struct DummyScanDescData *DummyScanDesc;
+
+/* parse table for fillRelOptions */
+static relopt_parse_elt dt_relopt_tab[7];
+
+/* Kind of relation options for dummy index */
+static relopt_kind dt_relopt_kind;
+
+typedef enum DummyAmEnum
+{
+	DUMMY_AM_ENUM_ONE,
+	DUMMY_AM_ENUM_TWO,
+}			DummyAmEnum;
+
+/* Dummy table options */
+typedef struct DummyTableOptions
+{
+	int32		vl_len_;		/* varlena header (do not touch directly!) */
+	int			option_int;
+	double		option_real;
+	bool		option_bool;
+	DummyAmEnum option_enum;
+	int			option_string_val_offset;
+	int			option_string_null_offset;
+	int			fillfactor;
+}			DummyTableOptions;
+
+static relopt_enum_elt_def dummyAmEnumValues[] =
+{
+	{"one", DUMMY_AM_ENUM_ONE},
+	{"two", DUMMY_AM_ENUM_TWO},
+	{(const char *) NULL}		/* list terminator */
+};
+
+/* ------------------------------------------------------------------------
+ *                     Dummy Access Method Interface
+ * ------------------------------------------------------------------------
+ */
+
+static const TupleTableSlotOps *
+dummy_slot_callbacks(Relation relation)
+{
+	return &TTSOpsMinimalTuple;
+}
+
+static TableScanDesc
+dummy_scan_begin(Relation relation, Snapshot snapshot, int nkeys, ScanKey key,
+				 ParallelTableScanDesc parallel_scan, uint32 flags)
+{
+	DummyScanDesc scan;
+
+	scan = (DummyScanDesc) palloc(sizeof(DummyScanDescData));
+
+	scan->rs_base.rs_rd = relation;
+	scan->rs_base.rs_snapshot = snapshot;
+	scan->rs_base.rs_nkeys = nkeys;
+	scan->rs_base.rs_flags = flags;
+	scan->rs_base.rs_parallel = parallel_scan;
+
+	return (TableScanDesc) scan;
+}
+
+static void
+dummy_scan_end(TableScanDesc sscan)
+{
+	DummyScanDesc scan = (DummyScanDesc) sscan;
+
+	pfree(scan);
+
+	return;
+}
+
+static void
+dummy_scan_rescan(TableScanDesc sscan, ScanKey key, bool set_params,
+				  bool allow_strat, bool allow_sync, bool allow_pagemode)
+{
+	return;
+}
+
+static bool
+dummy_scan_getnextslot(TableScanDesc sscan, ScanDirection direction,
+					   TupleTableSlot *slot)
+{
+	return true;
+}
+
+static void
+dummy_scan_set_tidrange(TableScanDesc sscan, ItemPointer mintid,
+						ItemPointer maxtid)
+{
+	return;
+}
+
+static bool
+dummy_scan_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction,
+								TupleTableSlot *slot)
+{
+	return true;
+}
+
+static Size
+dummy_parallelscan_estimate(Relation rel)
+{
+	return 0;
+}
+
+static Size
+dummy_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan)
+{
+	return 0;
+}
+
+static void
+dummy_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan)
+{
+	return;
+}
+
+static IndexFetchTableData *
+dummy_index_fetch_begin(Relation rel)
+{
+	return NULL;
+}
+
+static void
+dummy_index_fetch_reset(IndexFetchTableData *scan)
+{
+	return;
+}
+
+static void
+dummy_index_fetch_end(IndexFetchTableData *scan)
+{
+	return;
+}
+
+static bool
+dummy_index_fetch_tuple(struct IndexFetchTableData *scan, ItemPointer tid,
+						Snapshot snapshot, TupleTableSlot *slot,
+						bool *call_again, bool *all_dead)
+{
+	return true;
+}
+
+static void
+dummy_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid,
+				   int options, BulkInsertStateData *bistate)
+{
+	DummyTableOptions *relopts;
+
+	relopts = (DummyTableOptions *) relation->rd_options;
+
+	elog(NOTICE, "option_int=%d, option_real=%f, option_bool=%d, option_enum=%d",
+		 relopts->option_int, relopts->option_real, relopts->option_bool, relopts->option_enum);
+
+	return;
+}
+
+static void
+dummy_tuple_insert_speculative(Relation relation, TupleTableSlot *slot,
+							   CommandId cid, int options,
+							   BulkInsertStateData *bistate, uint32 specToken)
+{
+	return;
+}
+
+static void
+dummy_tuple_complete_speculative(Relation relation, TupleTableSlot *slot,
+								 uint32 specToken, bool succeeded)
+{
+	return;
+}
+
+static void
+dummy_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
+				   CommandId cid, int options, BulkInsertStateData *bistate)
+{
+	return;
+}
+
+static TM_Result
+dummy_tuple_delete(Relation relation, ItemPointer tid, CommandId cid,
+				   Snapshot snapshot, Snapshot crosscheck, bool wait,
+				   TM_FailureData *tmfd, bool changingPart)
+{
+	return TM_Ok;
+}
+
+static TM_Result
+dummy_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot,
+				   CommandId cid, Snapshot snapshot, Snapshot crosscheck,
+				   bool wait, TM_FailureData *tmfd,
+				   LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes)
+{
+	return TM_Ok;
+}
+
+static TM_Result
+dummy_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
+				 TupleTableSlot *slot, CommandId cid, LockTupleMode mode,
+				 LockWaitPolicy wait_policy, uint8 flags,
+				 TM_FailureData *tmfd)
+{
+	return TM_Ok;
+}
+
+static bool
+dummy_fetch_row_version(Relation relation, ItemPointer tid,
+						Snapshot snapshot, TupleTableSlot *slot)
+{
+	return false;
+}
+
+static void
+dummy_get_latest_tid(TableScanDesc sscan, ItemPointer tid)
+{
+	return;
+}
+
+static bool
+dummy_tuple_tid_valid(TableScanDesc scan, ItemPointer tid)
+{
+	return false;
+}
+
+static bool
+dummy_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot,
+							   Snapshot snapshot)
+{
+	return false;
+}
+
+static TransactionId
+dummy_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
+{
+	return InvalidTransactionId;
+}
+
+static void
+dummy_relation_set_new_filelocator(Relation rel,
+								   const RelFileLocator *newrlocator,
+								   char persistence,
+								   TransactionId *freezeXid,
+								   MultiXactId *minmulti)
+{
+	return;
+}
+
+static void
+dummy_relation_nontransactional_truncate(Relation rel)
+{
+	return;
+}
+
+static void
+dummy_relation_copy_data(Relation rel, const RelFileLocator *newrlocator)
+{
+	return;
+}
+
+static void
+dummy_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
+								Relation OldIndex, bool use_sort,
+								TransactionId OldestXmin,
+								TransactionId *xid_cutoff,
+								MultiXactId *multi_cutoff,
+								double *num_tuples,
+								double *tups_vacuumed,
+								double *tups_recently_dead)
+{
+	return;
+}
+
+static void
+dummy_relation_vacuum(Relation rel, struct VacuumParams *params,
+					  BufferAccessStrategy bstrategy)
+{
+	return;
+}
+
+static bool
+dummy_scan_analyze_next_block(TableScanDesc scan, ReadStream *stream)
+{
+	return false;
+}
+
+static bool
+dummy_scan_analyze_next_tuple(TableScanDesc scan, TransactionId OldestXmin,
+							  double *liverows, double *deadrows,
+							  TupleTableSlot *slot)
+{
+	return false;
+}
+
+static double
+dummy_index_build_range_scan(Relation heapRelation,
+							 Relation indexRelation,
+							 struct IndexInfo *indexInfo,
+							 bool allow_sync,
+							 bool anyvisible,
+							 bool progress,
+							 BlockNumber start_blockno,
+							 BlockNumber numblocks,
+							 IndexBuildCallback callback,
+							 void *callback_state,
+							 TableScanDesc scan)
+{
+	return 0;
+}
+
+static void
+dummy_index_validate_scan(Relation heapRelation,
+						  Relation indexRelation,
+						  struct IndexInfo *indexInfo,
+						  Snapshot snapshot,
+						  struct ValidateIndexState *state)
+{
+	return;
+}
+
+static uint64
+dummy_relation_size(Relation rel, ForkNumber forkNumber)
+{
+	return 0;
+}
+
+static bool
+dummy_relation_needs_toast_table(Relation rel)
+{
+	return false;
+}
+
+static Oid
+dummy_relation_toast_am(Relation rel)
+{
+	return InvalidOid;
+}
+
+static void
+dummy_relation_fetch_toast_slice(Relation toastrel, Oid valueid, int32 attrsize,
+								 int32 sliceoffset, int32 slicelength,
+								 struct varlena *result)
+{
+	return;
+}
+
+static void
+dummy_relation_estimate_size(Relation rel, int32 *attr_widths,
+							 BlockNumber *pages, double *tuples,
+							 double *allvisfrac)
+{
+	return;
+}
+
+static bool
+dummy_scan_bitmap_next_tuple(TableScanDesc scan, TupleTableSlot *slot,
+							 bool *recheck, uint64 *lossy_pages,
+							 uint64 *exact_pages)
+{
+	return false;
+}
+
+static bool
+dummy_scan_sample_next_block(TableScanDesc scan, struct SampleScanState *scanstate)
+{
+	return false;
+}
+
+static bool
+dummy_scan_sample_next_tuple(TableScanDesc scan, struct SampleScanState *scanstate,
+							 TupleTableSlot *slot)
+{
+	return false;
+}
+
+static bytea *
+dummy_relation_options(char relkind, Datum reloptions, bool validate)
+{
+	return (bytea *) build_reloptions(reloptions, validate,
+									  dt_relopt_kind,
+									  sizeof(DummyTableOptions),
+									  dt_relopt_tab, lengthof(dt_relopt_tab));
+}
+
+/*
+ * Validation function for string relation options.
+ */
+static void
+validate_string_option(const char *value)
+{
+	ereport(NOTICE,
+			(errmsg("new option value for string parameter %s",
+					value ? value : "NULL")));
+}
+
+/*
+ * This function creates a full set of relation option types,
+ * with various patterns.
+ */
+static void
+create_reloptions_table(void)
+{
+	dt_relopt_kind = add_reloption_kind();
+
+	add_int_reloption(dt_relopt_kind, "option_int",
+					  "Integer option for dummy_table_am",
+					  10, -10, 100, AccessExclusiveLock);
+	dt_relopt_tab[0].optname = "option_int";
+	dt_relopt_tab[0].opttype = RELOPT_TYPE_INT;
+	dt_relopt_tab[0].offset = offsetof(DummyTableOptions, option_int);
+
+	add_real_reloption(dt_relopt_kind, "option_real",
+					   "Real option for dummy_table_am",
+					   3.1415, -10, 100, AccessExclusiveLock);
+	dt_relopt_tab[1].optname = "option_real";
+	dt_relopt_tab[1].opttype = RELOPT_TYPE_REAL;
+	dt_relopt_tab[1].offset = offsetof(DummyTableOptions, option_real);
+
+	add_bool_reloption(dt_relopt_kind, "option_bool",
+					   "Boolean option for dummy_table_am",
+					   true, AccessExclusiveLock);
+	dt_relopt_tab[2].optname = "option_bool";
+	dt_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
+	dt_relopt_tab[2].offset = offsetof(DummyTableOptions, option_bool);
+
+	add_enum_reloption(dt_relopt_kind, "option_enum",
+					   "Enum option for dummy_table_am",
+					   dummyAmEnumValues,
+					   DUMMY_AM_ENUM_ONE,
+					   "Valid values are \"one\" and \"two\".",
+					   AccessExclusiveLock);
+	dt_relopt_tab[3].optname = "option_enum";
+	dt_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
+	dt_relopt_tab[3].offset = offsetof(DummyTableOptions, option_enum);
+
+	add_string_reloption(dt_relopt_kind, "option_string_val",
+						 "String option for dummy_table_am with non-NULL default",
+						 "DefaultValue", &validate_string_option,
+						 AccessExclusiveLock);
+	dt_relopt_tab[4].optname = "option_string_val";
+	dt_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
+	dt_relopt_tab[4].offset = offsetof(DummyTableOptions,
+									   option_string_val_offset);
+
+	/*
+	 * String option for dummy_table_am with NULL default, and without
+	 * description.
+	 */
+	add_string_reloption(dt_relopt_kind, "option_string_null",
+						 NULL,	/* description */
+						 NULL, &validate_string_option,
+						 AccessExclusiveLock);
+	dt_relopt_tab[5].optname = "option_string_null";
+	dt_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
+	dt_relopt_tab[5].offset = offsetof(DummyTableOptions,
+									   option_string_null_offset);
+
+	/*
+	 * fillfactor will be used to check reloption conversion when changing
+	 * table access method between heap AM and dummy_table_am.
+	 */
+	add_int_reloption(dt_relopt_kind, "fillfactor",
+					  "Fillfactor option for dummy_table_am",
+					  10, 0, 90, AccessExclusiveLock);
+	dt_relopt_tab[6].optname = "fillfactor";
+	dt_relopt_tab[6].opttype = RELOPT_TYPE_INT;
+	dt_relopt_tab[6].offset = offsetof(DummyTableOptions, fillfactor);
+}
+
+
+/*
+ * Table Access Method API
+ */
+static const TableAmRoutine dummy_table_am_methods = {
+	.type = T_TableAmRoutine,
+
+	.slot_callbacks = dummy_slot_callbacks,
+	.scan_begin = dummy_scan_begin,
+	.scan_end = dummy_scan_end,
+	.scan_rescan = dummy_scan_rescan,
+	.scan_getnextslot = dummy_scan_getnextslot,
+
+	.scan_set_tidrange = dummy_scan_set_tidrange,
+	.scan_getnextslot_tidrange = dummy_scan_getnextslot_tidrange,
+
+	.parallelscan_estimate = dummy_parallelscan_estimate,
+	.parallelscan_initialize = dummy_parallelscan_initialize,
+	.parallelscan_reinitialize = dummy_parallelscan_reinitialize,
+
+	.index_fetch_begin = dummy_index_fetch_begin,
+	.index_fetch_reset = dummy_index_fetch_reset,
+	.index_fetch_end = dummy_index_fetch_end,
+	.index_fetch_tuple = dummy_index_fetch_tuple,
+
+	.tuple_insert = dummy_tuple_insert,
+	.tuple_insert_speculative = dummy_tuple_insert_speculative,
+	.tuple_complete_speculative = dummy_tuple_complete_speculative,
+	.multi_insert = dummy_multi_insert,
+	.tuple_delete = dummy_tuple_delete,
+	.tuple_update = dummy_tuple_update,
+	.tuple_lock = dummy_tuple_lock,
+
+	.tuple_fetch_row_version = dummy_fetch_row_version,
+	.tuple_get_latest_tid = dummy_get_latest_tid,
+	.tuple_tid_valid = dummy_tuple_tid_valid,
+	.tuple_satisfies_snapshot = dummy_tuple_satisfies_snapshot,
+	.index_delete_tuples = dummy_index_delete_tuples,
+
+	.relation_set_new_filelocator = dummy_relation_set_new_filelocator,
+	.relation_nontransactional_truncate = dummy_relation_nontransactional_truncate,
+	.relation_copy_data = dummy_relation_copy_data,
+	.relation_copy_for_cluster = dummy_relation_copy_for_cluster,
+	.relation_vacuum = dummy_relation_vacuum,
+	.scan_analyze_next_block = dummy_scan_analyze_next_block,
+	.scan_analyze_next_tuple = dummy_scan_analyze_next_tuple,
+	.index_build_range_scan = dummy_index_build_range_scan,
+	.index_validate_scan = dummy_index_validate_scan,
+
+	.relation_size = dummy_relation_size,
+	.relation_needs_toast_table = dummy_relation_needs_toast_table,
+	.relation_toast_am = dummy_relation_toast_am,
+	.relation_fetch_toast_slice = dummy_relation_fetch_toast_slice,
+	.relation_estimate_size = dummy_relation_estimate_size,
+	.relation_options = dummy_relation_options,
+
+	.scan_bitmap_next_tuple = dummy_scan_bitmap_next_tuple,
+	.scan_sample_next_block = dummy_scan_sample_next_block,
+	.scan_sample_next_tuple = dummy_scan_sample_next_tuple
+};
+
+PG_FUNCTION_INFO_V1(dummy_table_am_handler);
+
+Datum
+dummy_table_am_handler(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_POINTER(&dummy_table_am_methods);
+}
+
+void
+_PG_init(void)
+{
+	create_reloptions_table();
+}
diff --git a/src/test/modules/dummy_table_am/dummy_table_am.control b/src/test/modules/dummy_table_am/dummy_table_am.control
new file mode 100644
index 00000000000..08f2f868d49
--- /dev/null
+++ b/src/test/modules/dummy_table_am/dummy_table_am.control
@@ -0,0 +1,5 @@
+# dummy_table_am extension
+comment = 'dummy_table_am - table access method template'
+default_version = '1.0'
+module_pathname = '$libdir/dummy_table_am'
+relocatable = true
diff --git a/src/test/modules/dummy_table_am/expected/reloptions.out b/src/test/modules/dummy_table_am/expected/reloptions.out
new file mode 100644
index 00000000000..0b947500ead
--- /dev/null
+++ b/src/test/modules/dummy_table_am/expected/reloptions.out
@@ -0,0 +1,181 @@
+-- Tests for relation options
+CREATE EXTENSION dummy_table_am;
+CREATE TABLE dummy_test_tab (i int4) USING dummy_table_am;
+-- Silence validation checks for strings
+SET client_min_messages TO 'warning';
+-- Test with default values.
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+ unnest 
+--------
+(0 rows)
+
+DROP TABLE dummy_test_tab;
+-- Test with full set of options.
+-- Allow validation checks for strings
+SET client_min_messages TO 'notice';
+CREATE TABLE dummy_test_tab (i int4)
+  USING dummy_table_am WITH (
+  option_bool = false,
+  option_int = 5,
+  option_real = 3.1,
+  option_enum = 'two',
+  option_string_val = NULL,
+  option_string_null = 'val');
+NOTICE:  new option value for string parameter null
+NOTICE:  new option value for string parameter val
+-- Silence again validation checks for strings until the end of the test.
+SET client_min_messages TO 'warning';
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+         unnest         
+------------------------
+ option_bool=false
+ option_int=5
+ option_real=3.1
+ option_enum=two
+ option_string_val=null
+ option_string_null=val
+(6 rows)
+
+-- ALTER TABLE .. SET
+ALTER TABLE dummy_test_tab SET (option_int = 10);
+ALTER TABLE dummy_test_tab SET (option_bool = true);
+ALTER TABLE dummy_test_tab SET (option_real = 3.2);
+ALTER TABLE dummy_test_tab SET (option_string_val = 'val2');
+ALTER TABLE dummy_test_tab SET (option_string_null = NULL);
+ALTER TABLE dummy_test_tab SET (option_enum = 'one');
+ALTER TABLE dummy_test_tab SET (option_enum = 'three');
+ERROR:  invalid value for enum option "option_enum": three
+DETAIL:  Valid values are "one" and "two".
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+         unnest          
+-------------------------
+ option_int=10
+ option_bool=true
+ option_real=3.2
+ option_string_val=val2
+ option_string_null=null
+ option_enum=one
+(6 rows)
+
+-- ALTER TABLE .. RESET
+ALTER TABLE dummy_test_tab RESET (option_int);
+ALTER TABLE dummy_test_tab RESET (option_bool);
+ALTER TABLE dummy_test_tab RESET (option_real);
+ALTER TABLE dummy_test_tab RESET (option_enum);
+ALTER TABLE dummy_test_tab RESET (option_string_val);
+ALTER TABLE dummy_test_tab RESET (option_string_null);
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+ unnest 
+--------
+(0 rows)
+
+-- Cross-type checks for reloption values
+-- Integer
+ALTER TABLE dummy_test_tab SET (option_int = 3.3); -- ok
+ALTER TABLE dummy_test_tab SET (option_int = true); -- error
+ERROR:  invalid value for integer option "option_int": true
+ALTER TABLE dummy_test_tab SET (option_int = 'val3'); -- error
+ERROR:  invalid value for integer option "option_int": val3
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+     unnest     
+----------------
+ option_int=3.3
+(1 row)
+
+ALTER TABLE dummy_test_tab RESET (option_int);
+-- Boolean
+ALTER TABLE dummy_test_tab SET (option_bool = 4); -- error
+ERROR:  invalid value for boolean option "option_bool": 4
+ALTER TABLE dummy_test_tab SET (option_bool = 1); -- ok, as true
+ALTER TABLE dummy_test_tab SET (option_bool = 3.4); -- error
+ERROR:  invalid value for boolean option "option_bool": 3.4
+ALTER TABLE dummy_test_tab SET (option_bool = 'val4'); -- error
+ERROR:  invalid value for boolean option "option_bool": val4
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+    unnest     
+---------------
+ option_bool=1
+(1 row)
+
+ALTER TABLE dummy_test_tab RESET (option_bool);
+-- Float
+ALTER TABLE dummy_test_tab SET (option_real = 4); -- ok
+ALTER TABLE dummy_test_tab SET (option_real = true); -- error
+ERROR:  invalid value for floating point option "option_real": true
+ALTER TABLE dummy_test_tab SET (option_real = 'val5'); -- error
+ERROR:  invalid value for floating point option "option_real": val5
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+    unnest     
+---------------
+ option_real=4
+(1 row)
+
+ALTER TABLE dummy_test_tab RESET (option_real);
+-- Enum
+ALTER TABLE dummy_test_tab SET (option_enum = 'one'); -- ok
+ALTER TABLE dummy_test_tab SET (option_enum = 0); -- error
+ERROR:  invalid value for enum option "option_enum": 0
+DETAIL:  Valid values are "one" and "two".
+ALTER TABLE dummy_test_tab SET (option_enum = true); -- error
+ERROR:  invalid value for enum option "option_enum": true
+DETAIL:  Valid values are "one" and "two".
+ALTER TABLE dummy_test_tab SET (option_enum = 'three'); -- error
+ERROR:  invalid value for enum option "option_enum": three
+DETAIL:  Valid values are "one" and "two".
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+     unnest      
+-----------------
+ option_enum=one
+(1 row)
+
+ALTER TABLE dummy_test_tab RESET (option_enum);
+-- String
+ALTER TABLE dummy_test_tab SET (option_string_val = 4); -- ok
+ALTER TABLE dummy_test_tab SET (option_string_val = 3.5); -- ok
+ALTER TABLE dummy_test_tab SET (option_string_val = true); -- ok, as "true"
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+         unnest         
+------------------------
+ option_string_val=true
+(1 row)
+
+ALTER TABLE dummy_test_tab RESET (option_string_val);
+DROP TABLE dummy_test_tab;
+-- ALTER TABLE SET ACCESS METHOD OPTIONS
+CREATE TABLE heap_tab (i INT4) WITH (fillfactor=100, toast_tuple_target=1000);
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'heap_tab';
+         unnest          
+-------------------------
+ fillfactor=100
+ toast_tuple_target=1000
+(2 rows)
+
+-- error: fillfactor is out of bounds: maximum value from the new table am is 90
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am;
+ERROR:  value 100 out of bounds for option "fillfactor"
+DETAIL:  Valid values are between "0" and "90".
+-- error: toast_tuple_target does not exist in the new table AM
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (SET fillfactor '50');
+ERROR:  unrecognized parameter "toast_tuple_target"
+-- error: adding is not possible when the parameter is already defined in source reloptions
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (ADD fillfactor '50');
+ERROR:  option "fillfactor" provided more than once
+-- error: the specified option we want to drop does not exist
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (DROP does_not_exist);
+ERROR:  option "does_not_exist" not found
+-- error: adding unrecognized parameter
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (SET fillfactor '50', DROP toast_tuple_target, ADD unrecognized 'foo');
+ERROR:  unrecognized parameter "unrecognized"
+-- ok
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (DROP fillfactor, DROP toast_tuple_target, option_int '1', option_bool 'true', option_real '0.001', option_enum 'one', option_string_val 'hello');
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'heap_tab';
+         unnest          
+-------------------------
+ option_int=1
+ option_bool=true
+ option_real=0.001
+ option_enum=one
+ option_string_val=hello
+(5 rows)
+
+DROP TABLE heap_tab;
diff --git a/src/test/modules/dummy_table_am/meson.build b/src/test/modules/dummy_table_am/meson.build
new file mode 100644
index 00000000000..6b197b15ffa
--- /dev/null
+++ b/src/test/modules/dummy_table_am/meson.build
@@ -0,0 +1,33 @@
+# Copyright (c) 2022-2025, PostgreSQL Global Development Group
+
+dummy_table_am_sources = files(
+  'dummy_table_am.c',
+)
+
+if host_system == 'windows'
+  dummy_table_am_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'dummy_table_am',
+    '--FILEDESC', 'dummy_table_am - table access method template',])
+endif
+
+dummy_table_am = shared_module('dummy_table_am',
+  dummy_table_am_sources,
+  kwargs: pg_test_mod_args,
+)
+test_install_libs += dummy_table_am
+
+test_install_data += files(
+  'dummy_table_am.control',
+  'dummy_table_am--1.0.sql',
+)
+
+tests += {
+  'name': 'dummy_table_am',
+  'sd': meson.current_source_dir(),
+  'bd': meson.current_build_dir(),
+  'regress': {
+    'sql': [
+      'reloptions',
+    ],
+  },
+}
diff --git a/src/test/modules/dummy_table_am/sql/reloptions.sql b/src/test/modules/dummy_table_am/sql/reloptions.sql
new file mode 100644
index 00000000000..47fb4862c6c
--- /dev/null
+++ b/src/test/modules/dummy_table_am/sql/reloptions.sql
@@ -0,0 +1,99 @@
+-- Tests for relation options
+CREATE EXTENSION dummy_table_am;
+
+CREATE TABLE dummy_test_tab (i int4) USING dummy_table_am;
+
+-- Silence validation checks for strings
+SET client_min_messages TO 'warning';
+
+-- Test with default values.
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+DROP TABLE dummy_test_tab;
+
+-- Test with full set of options.
+-- Allow validation checks for strings
+SET client_min_messages TO 'notice';
+CREATE TABLE dummy_test_tab (i int4)
+  USING dummy_table_am WITH (
+  option_bool = false,
+  option_int = 5,
+  option_real = 3.1,
+  option_enum = 'two',
+  option_string_val = NULL,
+  option_string_null = 'val');
+-- Silence again validation checks for strings until the end of the test.
+SET client_min_messages TO 'warning';
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+
+-- ALTER TABLE .. SET
+ALTER TABLE dummy_test_tab SET (option_int = 10);
+ALTER TABLE dummy_test_tab SET (option_bool = true);
+ALTER TABLE dummy_test_tab SET (option_real = 3.2);
+ALTER TABLE dummy_test_tab SET (option_string_val = 'val2');
+ALTER TABLE dummy_test_tab SET (option_string_null = NULL);
+ALTER TABLE dummy_test_tab SET (option_enum = 'one');
+ALTER TABLE dummy_test_tab SET (option_enum = 'three');
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+
+-- ALTER TABLE .. RESET
+ALTER TABLE dummy_test_tab RESET (option_int);
+ALTER TABLE dummy_test_tab RESET (option_bool);
+ALTER TABLE dummy_test_tab RESET (option_real);
+ALTER TABLE dummy_test_tab RESET (option_enum);
+ALTER TABLE dummy_test_tab RESET (option_string_val);
+ALTER TABLE dummy_test_tab RESET (option_string_null);
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+
+-- Cross-type checks for reloption values
+-- Integer
+ALTER TABLE dummy_test_tab SET (option_int = 3.3); -- ok
+ALTER TABLE dummy_test_tab SET (option_int = true); -- error
+ALTER TABLE dummy_test_tab SET (option_int = 'val3'); -- error
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+ALTER TABLE dummy_test_tab RESET (option_int);
+-- Boolean
+ALTER TABLE dummy_test_tab SET (option_bool = 4); -- error
+ALTER TABLE dummy_test_tab SET (option_bool = 1); -- ok, as true
+ALTER TABLE dummy_test_tab SET (option_bool = 3.4); -- error
+ALTER TABLE dummy_test_tab SET (option_bool = 'val4'); -- error
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+ALTER TABLE dummy_test_tab RESET (option_bool);
+-- Float
+ALTER TABLE dummy_test_tab SET (option_real = 4); -- ok
+ALTER TABLE dummy_test_tab SET (option_real = true); -- error
+ALTER TABLE dummy_test_tab SET (option_real = 'val5'); -- error
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+ALTER TABLE dummy_test_tab RESET (option_real);
+-- Enum
+ALTER TABLE dummy_test_tab SET (option_enum = 'one'); -- ok
+ALTER TABLE dummy_test_tab SET (option_enum = 0); -- error
+ALTER TABLE dummy_test_tab SET (option_enum = true); -- error
+ALTER TABLE dummy_test_tab SET (option_enum = 'three'); -- error
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+ALTER TABLE dummy_test_tab RESET (option_enum);
+-- String
+ALTER TABLE dummy_test_tab SET (option_string_val = 4); -- ok
+ALTER TABLE dummy_test_tab SET (option_string_val = 3.5); -- ok
+ALTER TABLE dummy_test_tab SET (option_string_val = true); -- ok, as "true"
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_tab';
+ALTER TABLE dummy_test_tab RESET (option_string_val);
+
+DROP TABLE dummy_test_tab;
+
+-- ALTER TABLE SET ACCESS METHOD OPTIONS
+CREATE TABLE heap_tab (i INT4) WITH (fillfactor=100, toast_tuple_target=1000);
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'heap_tab';
+-- error: fillfactor is out of bounds: maximum value from the new table am is 90
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am;
+-- error: toast_tuple_target does not exist in the new table AM
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (SET fillfactor '50');
+-- error: adding is not possible when the parameter is already defined in source reloptions
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (ADD fillfactor '50');
+-- error: the specified option we want to drop does not exist
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (DROP does_not_exist);
+-- error: adding unrecognized parameter
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (SET fillfactor '50', DROP toast_tuple_target, ADD unrecognized 'foo');
+-- ok
+ALTER TABLE heap_tab SET ACCESS METHOD dummy_table_am OPTIONS (DROP fillfactor, DROP toast_tuple_target, option_int '1', option_bool 'true', option_real '0.001', option_enum 'one', option_string_val 'hello');
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'heap_tab';
+DROP TABLE heap_tab;
diff --git a/src/test/modules/meson.build b/src/test/modules/meson.build
index 2b057451473..28398254df7 100644
--- a/src/test/modules/meson.build
+++ b/src/test/modules/meson.build
@@ -4,6 +4,7 @@ subdir('brin')
 subdir('commit_ts')
 subdir('delay_execution')
 subdir('dummy_index_am')
+subdir('dummy_table_am')
 subdir('dummy_seclabel')
 subdir('gin')
 subdir('injection_points')
-- 
2.39.5


--jr4jupeetksdtvhn--





^ permalink  raw  reply  [nested|flat] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

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

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

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

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

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

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

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

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

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

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] 808+ 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; 808+ messages in thread

From: Bertrand Drouvot @ 2025-08-08 15:58 UTC (permalink / raw)

This commit adds a new counter to record the number of XIDs generated per
backend. It will help to detect if a backend is consuming XIDs at a high rate.

Virtual transactions are not taken into account on purpose, we do want to track
only the XID where there is a risk of wraparound.
---
 src/backend/access/transam/varsup.c         | 4 ++++
 src/backend/utils/activity/pgstat_backend.c | 2 ++
 src/include/pgstat.h                        | 2 ++
 3 files changed, 8 insertions(+)
  43.8% src/backend/access/transam/
  36.6% src/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] 808+ messages in thread


end of thread, other threads:[~2025-08-08 15:58 UTC | newest]

Thread overview: 808+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2025-03-01 19:50 [PATCH 2/2] Add the "dummy_table_am" test module Julien Tachoires <[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 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 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 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 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 v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 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 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 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 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 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 v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 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 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 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v5 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v3 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH v4 2/3] Adding XID generation count per backend Bertrand Drouvot <[email protected]>
2025-08-08 15:58 [PATCH 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 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 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 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 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 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 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 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]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox