From d4ba8b51c76300f06cc23f4d8a41d9f7210c4866 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Sun, 20 Mar 2022 19:12:09 -0700 Subject: [PATCH] pgstat: separate "xact level" handling out of relation specific functions. This is in preparation of a later commit moving relation stats handling into its own file. Author: Andres Freund Discussion: https://postgr.es/m/20220303021600.hs34ghqcw6zcokdh@alap3.anarazel.de --- src/backend/postmaster/pgstat.c | 68 +++++++++++++++++---------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index e90b456006..ab47a083c3 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -235,16 +235,24 @@ static bool have_relation_stats = false; 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; @@ -2305,10 +2313,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; @@ -2339,7 +2348,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 *) @@ -2353,6 +2362,19 @@ 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 */ @@ -2362,13 +2384,8 @@ 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; } } @@ -2382,13 +2399,8 @@ 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 */ @@ -2406,13 +2418,8 @@ 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++; } } @@ -2463,13 +2470,8 @@ 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; @@ -2656,7 +2658,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;