From: Andres Freund Date: Wed, 2 Mar 2022 18:02:03 -0800 Subject: [PATCH v65 02/11] pgstat: Introduce pgstat_relation_should_count(). --- src/include/pgstat.h | 27 +++++++++---- src/include/utils/rel.h | 1 + src/backend/access/common/relation.c | 4 +- src/backend/catalog/index.c | 2 +- src/backend/postmaster/pgstat.c | 59 +++++++++++++++++----------- 5 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/include/pgstat.h b/src/include/pgstat.h index be2f7e2bcc7..f808955125b 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -1102,43 +1102,54 @@ extern void pgstat_initialize(void); extern PgStat_TableStatus *find_tabstat_entry(Oid rel_id); extern PgStat_BackendFunctionEntry *find_funcstat_entry(Oid func_id); -extern void pgstat_initstats(Relation rel); +extern void pgstat_relation_init(Relation rel); +extern void pgstat_relation_assoc(Relation rel); + +/* + * AFIXME: pgstat_enabled should instead be tri-valued (disabled, + * needs-initialization, initialized). Then we don't need to check two + * separate variables. + */ +#define pgstat_relation_should_count(rel) \ + (likely((rel)->pgstat_info != NULL) ? true : \ + ((rel)->pgstat_enabled ? pgstat_relation_assoc(rel), true : false)) + /* nontransactional event counts are simple enough to inline */ #define pgstat_count_heap_scan(rel) \ do { \ - if ((rel)->pgstat_info != NULL) \ + if (pgstat_relation_should_count(rel)) \ (rel)->pgstat_info->t_counts.t_numscans++; \ } while (0) #define pgstat_count_heap_getnext(rel) \ do { \ - if ((rel)->pgstat_info != NULL) \ + if (pgstat_relation_should_count(rel)) \ (rel)->pgstat_info->t_counts.t_tuples_returned++; \ } while (0) #define pgstat_count_heap_fetch(rel) \ do { \ - if ((rel)->pgstat_info != NULL) \ + if (pgstat_relation_should_count(rel)) \ (rel)->pgstat_info->t_counts.t_tuples_fetched++; \ } while (0) #define pgstat_count_index_scan(rel) \ do { \ - if ((rel)->pgstat_info != NULL) \ + if (pgstat_relation_should_count(rel)) \ (rel)->pgstat_info->t_counts.t_numscans++; \ } while (0) #define pgstat_count_index_tuples(rel, n) \ do { \ - if ((rel)->pgstat_info != NULL) \ + if (pgstat_relation_should_count(rel)) \ (rel)->pgstat_info->t_counts.t_tuples_returned += (n); \ } while (0) #define pgstat_count_buffer_read(rel) \ do { \ - if ((rel)->pgstat_info != NULL) \ + if (pgstat_relation_should_count(rel)) \ (rel)->pgstat_info->t_counts.t_blocks_fetched++; \ } while (0) #define pgstat_count_buffer_hit(rel) \ do { \ - if ((rel)->pgstat_info != NULL) \ + if (pgstat_relation_should_count(rel)) \ (rel)->pgstat_info->t_counts.t_blocks_hit++; \ } while (0) #define pgstat_count_buffer_read_time(n) \ diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 3b4ab65ae20..485d38ecee3 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -247,6 +247,7 @@ typedef struct RelationData Oid rd_toastoid; /* Real TOAST table's OID, or InvalidOid */ /* use "struct" here to avoid needing to include pgstat.h: */ + bool pgstat_enabled; struct PgStat_TableStatus *pgstat_info; /* statistics collection area */ } RelationData; diff --git a/src/backend/access/common/relation.c b/src/backend/access/common/relation.c index 1c02bf03a34..003663ab811 100644 --- a/src/backend/access/common/relation.c +++ b/src/backend/access/common/relation.c @@ -73,7 +73,7 @@ relation_open(Oid relationId, LOCKMODE lockmode) if (RelationUsesLocalBuffers(r)) MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; - pgstat_initstats(r); + pgstat_relation_init(r); return r; } @@ -123,7 +123,7 @@ try_relation_open(Oid relationId, LOCKMODE lockmode) if (RelationUsesLocalBuffers(r)) MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; - pgstat_initstats(r); + pgstat_relation_init(r); return r; } diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 5e3fc2b35dc..a9e69b8122b 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -1743,7 +1743,7 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName) tabentry = pgstat_fetch_stat_tabentry(oldIndexId); if (tabentry) { - if (newClassRel->pgstat_info) + if (pgstat_relation_should_count(newClassRel)) { newClassRel->pgstat_info->t_counts.t_numscans = tabentry->numscans; newClassRel->pgstat_info->t_counts.t_tuples_returned = tabentry->tuples_returned; diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 53ddd930e6e..de45a10334b 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -188,7 +188,7 @@ static bool pgStatRunningInCollector = false; * for the life of the backend. Also, we zero out the t_id fields of the * contained PgStat_TableStatus structs whenever they are not actively in use. * This allows relcache pgstat_info pointers to be treated as long-lived data, - * avoiding repeated searches in pgstat_initstats() when a relation is + * avoiding repeated searches in pgstat_relation_assoc() when a relation is * repeatedly opened during a transaction. */ #define TABSTAT_QUANTUM 100 /* we alloc this many at a time */ @@ -1683,7 +1683,7 @@ pgstat_report_analyze(Relation rel, * * Waste no time on partitioned tables, though. */ - if (rel->pgstat_info != NULL && + if (pgstat_relation_should_count(rel) && rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) { PgStat_TableXactStatus *trans; @@ -2121,7 +2121,7 @@ pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize) /* ---------- - * pgstat_initstats() - + * pgstat_relation_init() - * * Initialize a relcache entry to count access statistics. * Called whenever a relation is opened. @@ -2133,7 +2133,7 @@ pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize) * ---------- */ void -pgstat_initstats(Relation rel) +pgstat_relation_init(Relation rel) { Oid rel_id = rel->rd_id; char relkind = rel->rd_rel->relkind; @@ -2143,6 +2143,7 @@ pgstat_initstats(Relation rel) */ if (!RELKIND_HAS_STORAGE(relkind) && relkind != RELKIND_PARTITIONED_TABLE) { + rel->pgstat_enabled = false; rel->pgstat_info = NULL; return; } @@ -2150,6 +2151,7 @@ pgstat_initstats(Relation rel) if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts) { /* We're not counting at all */ + rel->pgstat_enabled = false; rel->pgstat_info = NULL; return; } @@ -2158,11 +2160,22 @@ pgstat_initstats(Relation rel) * If we already set up this relation in the current transaction, nothing * to do. */ - if (rel->pgstat_info != NULL && + if (rel->pgstat_info && rel->pgstat_info->t_id == rel_id) return; - /* Else find or make the PgStat_TableStatus entry, and update link */ + rel->pgstat_enabled = true; +} + +void +pgstat_relation_assoc(Relation rel) +{ + Oid rel_id = rel->rd_id; + + Assert(rel->pgstat_enabled); + Assert(rel->pgstat_info == NULL); + + /* find or make the PgStat_TableStatus entry, and update link */ rel->pgstat_info = get_tabstat_entry(rel_id, rel->rd_rel->relisshared); } @@ -2331,13 +2344,12 @@ add_tabstat_xact_level(PgStat_TableStatus *pgstat_info, int nest_level) void pgstat_count_heap_insert(Relation rel, PgStat_Counter n) { - PgStat_TableStatus *pgstat_info = rel->pgstat_info; - - if (pgstat_info != NULL) + if (pgstat_relation_should_count(rel)) { - /* We have to log the effect at the proper transactional level */ + 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); @@ -2352,13 +2364,12 @@ pgstat_count_heap_insert(Relation rel, PgStat_Counter n) void pgstat_count_heap_update(Relation rel, bool hot) { - PgStat_TableStatus *pgstat_info = rel->pgstat_info; - - if (pgstat_info != NULL) + if (pgstat_relation_should_count(rel)) { - /* We have to log the effect at the proper transactional level */ + 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); @@ -2377,13 +2388,12 @@ pgstat_count_heap_update(Relation rel, bool hot) void pgstat_count_heap_delete(Relation rel) { - PgStat_TableStatus *pgstat_info = rel->pgstat_info; - - if (pgstat_info != NULL) + if (pgstat_relation_should_count(rel)) { - /* We have to log the effect at the proper transactional level */ + 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); @@ -2435,13 +2445,12 @@ pgstat_truncdrop_restore_counters(PgStat_TableXactStatus *trans) void pgstat_count_truncate(Relation rel) { - PgStat_TableStatus *pgstat_info = rel->pgstat_info; - - if (pgstat_info != NULL) + if (pgstat_relation_should_count(rel)) { - /* We have to log the effect at the proper transactional level */ + 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); @@ -2464,10 +2473,12 @@ pgstat_count_truncate(Relation rel) void pgstat_update_heap_dead_tuples(Relation rel, int delta) { - PgStat_TableStatus *pgstat_info = rel->pgstat_info; + if (pgstat_relation_should_count(rel)) + { + PgStat_TableStatus *pgstat_info = rel->pgstat_info; - if (pgstat_info != NULL) pgstat_info->t_counts.t_delta_dead_tuples -= delta; + } } /* -- 2.35.1.354.g715d08a9e5 --6rwz5pdckqwec52m Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v65-0003-pgstat-xact-level-cleanups-consolidation.patch"