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 <andres@anarazel.de>
Discussion: https://postgr.es/m/20220303021600.hs34ghqcw6zcokdh@alap3.anarazel.de
This commit is contained in:
Andres Freund 2022-03-20 19:12:09 -07:00
parent bff258a273
commit d4ba8b51c7

View File

@ -235,16 +235,24 @@ static bool have_relation_stats = false;
static bool have_function_stats = false; static bool have_function_stats = false;
/* /*
* Tuple insertion/deletion counts for an open transaction can't be propagated * Some stats changes are transactional. To maintain those, a stack of
* into PgStat_TableStatus counters until we know if it is going to commit * PgStat_SubXactStatus entries is maintained, which contain data pertaining
* or abort. Hence, we keep these counts in per-subxact structs that live * to the current transaction and its active subtransactions.
* in TopTransactionContext. This data structure is designed on the assumption
* that subxacts won't usually modify very many tables.
*/ */
typedef struct PgStat_SubXactStatus typedef struct PgStat_SubXactStatus
{ {
int nest_level; /* subtransaction nest level */ int nest_level; /* subtransaction nest level */
struct PgStat_SubXactStatus *prev; /* higher-level subxact if any */ 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_TableXactStatus *first; /* head of list for this subxact */
} PgStat_SubXactStatus; } 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 * static PgStat_SubXactStatus *
get_tabstat_stack_level(int nest_level) pgstat_xact_stack_level_get(int nest_level)
{ {
PgStat_SubXactStatus *xact_state; 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 * If this is the first rel to be modified at the current nest level, we
* first have to push a transaction stack entry. * 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 */ /* Now make a per-table stack entry */
trans = (PgStat_TableXactStatus *) trans = (PgStat_TableXactStatus *)
@ -2353,6 +2362,19 @@ add_tabstat_xact_level(PgStat_TableStatus *pgstat_info, int nest_level)
pgstat_info->trans = trans; 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 * 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)) if (pgstat_relation_should_count(rel))
{ {
PgStat_TableStatus *pgstat_info = rel->pgstat_info; 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; pgstat_info->trans->tuples_inserted += n;
} }
} }
@ -2382,13 +2399,8 @@ pgstat_count_heap_update(Relation rel, bool hot)
if (pgstat_relation_should_count(rel)) if (pgstat_relation_should_count(rel))
{ {
PgStat_TableStatus *pgstat_info = rel->pgstat_info; 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++; pgstat_info->trans->tuples_updated++;
/* t_tuples_hot_updated is nontransactional, so just advance it */ /* 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)) if (pgstat_relation_should_count(rel))
{ {
PgStat_TableStatus *pgstat_info = rel->pgstat_info; 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++; pgstat_info->trans->tuples_deleted++;
} }
} }
@ -2463,13 +2470,8 @@ pgstat_count_truncate(Relation rel)
if (pgstat_relation_should_count(rel)) if (pgstat_relation_should_count(rel))
{ {
PgStat_TableStatus *pgstat_info = rel->pgstat_info; 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_truncdrop_save_counters(pgstat_info->trans, false);
pgstat_info->trans->tuples_inserted = 0; pgstat_info->trans->tuples_inserted = 0;
pgstat_info->trans->tuples_updated = 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; 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; trans->next = upper_xact_state->first;
upper_xact_state->first = trans; upper_xact_state->first = trans;
trans->nest_level = nestDepth - 1; trans->nest_level = nestDepth - 1;