@@ -235,16 +235,24 @@ static bool have_relation_stats = false;
235235static bool have_function_stats = false;
236236
237237/*
238- * Tuple insertion/deletion counts for an open transaction can't be propagated
239- * into PgStat_TableStatus counters until we know if it is going to commit
240- * or abort. Hence, we keep these counts in per-subxact structs that live
241- * in TopTransactionContext. This data structure is designed on the assumption
242- * that subxacts won't usually modify very many tables.
238+ * Some stats changes are transactional. To maintain those, a stack of
239+ * PgStat_SubXactStatus entries is maintained, which contain data pertaining
240+ * to the current transaction and its active subtransactions.
243241 */
244242typedef struct PgStat_SubXactStatus
245243{
246244 int nest_level ; /* subtransaction nest level */
245+
247246 struct PgStat_SubXactStatus * prev ; /* higher-level subxact if any */
247+
248+ /*
249+ * Tuple insertion/deletion counts for an open transaction can't be
250+ * propagated into PgStat_TableStatus counters until we know if it is
251+ * going to commit or abort. Hence, we keep these counts in per-subxact
252+ * structs that live in TopTransactionContext. This data structure is
253+ * designed on the assumption that subxacts won't usually modify very many
254+ * tables.
255+ */
248256 PgStat_TableXactStatus * first ; /* head of list for this subxact */
249257} PgStat_SubXactStatus ;
250258
@@ -2305,10 +2313,11 @@ find_tabstat_entry(Oid rel_id)
23052313}
23062314
23072315/*
2308- * get_tabstat_stack_level - add a new (sub)transaction stack entry if needed
2316+ * Ensure (sub)transaction stack entry for the given nest_level exists, adding
2317+ * it if needed.
23092318 */
23102319static PgStat_SubXactStatus *
2311- get_tabstat_stack_level (int nest_level )
2320+ pgstat_xact_stack_level_get (int nest_level )
23122321{
23132322 PgStat_SubXactStatus * xact_state ;
23142323
@@ -2339,7 +2348,7 @@ add_tabstat_xact_level(PgStat_TableStatus *pgstat_info, int nest_level)
23392348 * If this is the first rel to be modified at the current nest level, we
23402349 * first have to push a transaction stack entry.
23412350 */
2342- xact_state = get_tabstat_stack_level (nest_level );
2351+ xact_state = pgstat_xact_stack_level_get (nest_level );
23432352
23442353 /* Now make a per-table stack entry */
23452354 trans = (PgStat_TableXactStatus * )
@@ -2353,6 +2362,19 @@ add_tabstat_xact_level(PgStat_TableStatus *pgstat_info, int nest_level)
23532362 pgstat_info -> trans = trans ;
23542363}
23552364
2365+ /*
2366+ * Add a new (sub)transaction record if needed.
2367+ */
2368+ static void
2369+ ensure_tabstat_xact_level (PgStat_TableStatus * pgstat_info )
2370+ {
2371+ int nest_level = GetCurrentTransactionNestLevel ();
2372+
2373+ if (pgstat_info -> trans == NULL ||
2374+ pgstat_info -> trans -> nest_level != nest_level )
2375+ add_tabstat_xact_level (pgstat_info , nest_level );
2376+ }
2377+
23562378/*
23572379 * pgstat_count_heap_insert - count a tuple insertion of n tuples
23582380 */
@@ -2362,13 +2384,8 @@ pgstat_count_heap_insert(Relation rel, PgStat_Counter n)
23622384 if (pgstat_relation_should_count (rel ))
23632385 {
23642386 PgStat_TableStatus * pgstat_info = rel -> pgstat_info ;
2365- int nest_level = GetCurrentTransactionNestLevel ();
2366-
2367- /* We have to log the effect at the proper transactional level */
2368- if (pgstat_info -> trans == NULL ||
2369- pgstat_info -> trans -> nest_level != nest_level )
2370- add_tabstat_xact_level (pgstat_info , nest_level );
23712387
2388+ ensure_tabstat_xact_level (pgstat_info );
23722389 pgstat_info -> trans -> tuples_inserted += n ;
23732390 }
23742391}
@@ -2382,13 +2399,8 @@ pgstat_count_heap_update(Relation rel, bool hot)
23822399 if (pgstat_relation_should_count (rel ))
23832400 {
23842401 PgStat_TableStatus * pgstat_info = rel -> pgstat_info ;
2385- int nest_level = GetCurrentTransactionNestLevel ();
2386-
2387- /* We have to log the effect at the proper transactional level */
2388- if (pgstat_info -> trans == NULL ||
2389- pgstat_info -> trans -> nest_level != nest_level )
2390- add_tabstat_xact_level (pgstat_info , nest_level );
23912402
2403+ ensure_tabstat_xact_level (pgstat_info );
23922404 pgstat_info -> trans -> tuples_updated ++ ;
23932405
23942406 /* t_tuples_hot_updated is nontransactional, so just advance it */
@@ -2406,13 +2418,8 @@ pgstat_count_heap_delete(Relation rel)
24062418 if (pgstat_relation_should_count (rel ))
24072419 {
24082420 PgStat_TableStatus * pgstat_info = rel -> pgstat_info ;
2409- int nest_level = GetCurrentTransactionNestLevel ();
2410-
2411- /* We have to log the effect at the proper transactional level */
2412- if (pgstat_info -> trans == NULL ||
2413- pgstat_info -> trans -> nest_level != nest_level )
2414- add_tabstat_xact_level (pgstat_info , nest_level );
24152421
2422+ ensure_tabstat_xact_level (pgstat_info );
24162423 pgstat_info -> trans -> tuples_deleted ++ ;
24172424 }
24182425}
@@ -2463,13 +2470,8 @@ pgstat_count_truncate(Relation rel)
24632470 if (pgstat_relation_should_count (rel ))
24642471 {
24652472 PgStat_TableStatus * pgstat_info = rel -> pgstat_info ;
2466- int nest_level = GetCurrentTransactionNestLevel ();
2467-
2468- /* We have to log the effect at the proper transactional level */
2469- if (pgstat_info -> trans == NULL ||
2470- pgstat_info -> trans -> nest_level != nest_level )
2471- add_tabstat_xact_level (pgstat_info , nest_level );
24722473
2474+ ensure_tabstat_xact_level (pgstat_info );
24732475 pgstat_truncdrop_save_counters (pgstat_info -> trans , false);
24742476 pgstat_info -> trans -> tuples_inserted = 0 ;
24752477 pgstat_info -> trans -> tuples_updated = 0 ;
@@ -2656,7 +2658,7 @@ AtEOSubXact_PgStat_Relations(PgStat_SubXactStatus *xact_state, bool isCommit, in
26562658 */
26572659 PgStat_SubXactStatus * upper_xact_state ;
26582660
2659- upper_xact_state = get_tabstat_stack_level (nestDepth - 1 );
2661+ upper_xact_state = pgstat_xact_stack_level_get (nestDepth - 1 );
26602662 trans -> next = upper_xact_state -> first ;
26612663 upper_xact_state -> first = trans ;
26622664 trans -> nest_level = nestDepth - 1 ;
0 commit comments