From 5d26fdec467dc9942c3b608528c5b2f3f65a7971 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Wed, 2 Mar 2022 18:02:03 -0800
Subject: [PATCH v65 03/11] pgstat: xact level cleanups / consolidation.

---
 src/backend/postmaster/pgstat.c | 72 ++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index de45a10334b..1f5d95e2f40 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -229,16 +229,24 @@ static HTAB *pgStatFunctions = NULL;
 static bool have_function_stats = false;
 
 /*
- * Tuple insertion/deletion counts for an open transaction can't be propagated
- * into PgStat_TableStatus counters until we know if it is going to commit
- * or abort.  Hence, we keep these counts in per-subxact structs that live
- * in TopTransactionContext.  This data structure is designed on the assumption
- * that subxacts won't usually modify very many tables.
+ * Some stats changes are transactional. To maintain those, a stack of
+ * PgStat_SubXactStatus entries is maintained, which contain data pertaining
+ * to the current transaction and its active subtransactions.
  */
 typedef struct PgStat_SubXactStatus
 {
 	int			nest_level;		/* subtransaction nest level */
+
 	struct PgStat_SubXactStatus *prev;	/* higher-level subxact if any */
+
+	/*
+	 * Tuple insertion/deletion counts for an open transaction can't be
+	 * propagated into PgStat_TableStatus counters until we know if it is
+	 * going to commit or abort.  Hence, we keep these counts in per-subxact
+	 * structs that live in TopTransactionContext.  This data structure is
+	 * designed on the assumption that subxacts won't usually modify very many
+	 * tables.
+	 */
 	PgStat_TableXactStatus *first;	/* head of list for this subxact */
 } PgStat_SubXactStatus;
 
@@ -2290,10 +2298,11 @@ find_tabstat_entry(Oid rel_id)
 }
 
 /*
- * get_tabstat_stack_level - add a new (sub)transaction stack entry if needed
+ * Ensure (sub)transaction stack entry for the given nest_level exists, adding
+ * it if needed.
  */
 static PgStat_SubXactStatus *
-get_tabstat_stack_level(int nest_level)
+pgstat_xact_stack_level_get(int nest_level)
 {
 	PgStat_SubXactStatus *xact_state;
 
@@ -2324,7 +2333,7 @@ add_tabstat_xact_level(PgStat_TableStatus *pgstat_info, int nest_level)
 	 * If this is the first rel to be modified at the current nest level, we
 	 * first have to push a transaction stack entry.
 	 */
-	xact_state = get_tabstat_stack_level(nest_level);
+	xact_state = pgstat_xact_stack_level_get(nest_level);
 
 	/* Now make a per-table stack entry */
 	trans = (PgStat_TableXactStatus *)
@@ -2338,22 +2347,31 @@ add_tabstat_xact_level(PgStat_TableStatus *pgstat_info, int nest_level)
 	pgstat_info->trans = trans;
 }
 
+/*
+ * Add a new (sub)transaction record if needed.
+ */
+static void
+ensure_tabstat_xact_level(PgStat_TableStatus *pgstat_info)
+{
+	int			nest_level = GetCurrentTransactionNestLevel();
+
+	if (pgstat_info->trans == NULL ||
+		pgstat_info->trans->nest_level != nest_level)
+		add_tabstat_xact_level(pgstat_info, nest_level);
+}
+
 /*
  * pgstat_count_heap_insert - count a tuple insertion of n tuples
  */
 void
 pgstat_count_heap_insert(Relation rel, PgStat_Counter n)
 {
+
 	if (pgstat_relation_should_count(rel))
 	{
 		PgStat_TableStatus *pgstat_info = rel->pgstat_info;
-		int			nest_level = GetCurrentTransactionNestLevel();
-
-		/* We have to log the effect at the proper transactional level */
-		if (pgstat_info->trans == NULL ||
-			pgstat_info->trans->nest_level != nest_level)
-			add_tabstat_xact_level(pgstat_info, nest_level);
 
+		ensure_tabstat_xact_level(pgstat_info);
 		pgstat_info->trans->tuples_inserted += n;
 	}
 }
@@ -2364,16 +2382,12 @@ pgstat_count_heap_insert(Relation rel, PgStat_Counter n)
 void
 pgstat_count_heap_update(Relation rel, bool hot)
 {
+
 	if (pgstat_relation_should_count(rel))
 	{
 		PgStat_TableStatus *pgstat_info = rel->pgstat_info;
-		int			nest_level = GetCurrentTransactionNestLevel();
-
-		/* We have to log the effect at the proper transactional level */
-		if (pgstat_info->trans == NULL ||
-			pgstat_info->trans->nest_level != nest_level)
-			add_tabstat_xact_level(pgstat_info, nest_level);
 
+		ensure_tabstat_xact_level(pgstat_info);
 		pgstat_info->trans->tuples_updated++;
 
 		/* t_tuples_hot_updated is nontransactional, so just advance it */
@@ -2388,16 +2402,12 @@ pgstat_count_heap_update(Relation rel, bool hot)
 void
 pgstat_count_heap_delete(Relation rel)
 {
+
 	if (pgstat_relation_should_count(rel))
 	{
 		PgStat_TableStatus *pgstat_info = rel->pgstat_info;
-		int			nest_level = GetCurrentTransactionNestLevel();
-
-		/* We have to log the effect at the proper transactional level */
-		if (pgstat_info->trans == NULL ||
-			pgstat_info->trans->nest_level != nest_level)
-			add_tabstat_xact_level(pgstat_info, nest_level);
 
+		ensure_tabstat_xact_level(pgstat_info);
 		pgstat_info->trans->tuples_deleted++;
 	}
 }
@@ -2445,16 +2455,12 @@ pgstat_truncdrop_restore_counters(PgStat_TableXactStatus *trans)
 void
 pgstat_count_truncate(Relation rel)
 {
+
 	if (pgstat_relation_should_count(rel))
 	{
 		PgStat_TableStatus *pgstat_info = rel->pgstat_info;
-		int			nest_level = GetCurrentTransactionNestLevel();
-
-		/* We have to log the effect at the proper transactional level */
-		if (pgstat_info->trans == NULL ||
-			pgstat_info->trans->nest_level != nest_level)
-			add_tabstat_xact_level(pgstat_info, nest_level);
 
+		ensure_tabstat_xact_level(pgstat_info);
 		pgstat_truncdrop_save_counters(pgstat_info->trans, false);
 		pgstat_info->trans->tuples_inserted = 0;
 		pgstat_info->trans->tuples_updated = 0;
@@ -2641,7 +2647,7 @@ AtEOSubXact_PgStat_Relations(PgStat_SubXactStatus *xact_state, bool isCommit, in
 				 */
 				PgStat_SubXactStatus *upper_xact_state;
 
-				upper_xact_state = get_tabstat_stack_level(nestDepth - 1);
+				upper_xact_state = pgstat_xact_stack_level_get(nestDepth - 1);
 				trans->next = upper_xact_state->first;
 				upper_xact_state->first = trans;
 				trans->nest_level = nestDepth - 1;
-- 
2.35.1.354.g715d08a9e5

