From 2defd00062555c03f7ac4d8f004b98b36b876c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Mon, 12 Jan 2026 16:59:28 +0100 Subject: [PATCH] Move instrumentation-related structs to instrument_node.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some structs and enums related to parallel query instrumentation had organically grown scattered across various files, and were causing header pollution especially through execnodes.h. Create a single file where they can live together. This only moves the structs to the new file; cleaning up the pollution by removing no-longer-necessary cross-header inclusion will be done in future commits. Co-authored-by: Álvaro Herrera Co-authored-by: Mario González Reviewed-by: Chao Li Discussion: https://postgr.es/m/202510051642.wwmn4mj77wch@alvherre.pgsql Discussion: https://postgr.es/m/CAFsReFUr4KrQ60z+ck9cRM4WuUw1TCghN7EFwvV0KvuncTRc2w@mail.gmail.com --- contrib/bloom/blscan.c | 1 + src/backend/access/gin/ginscan.c | 1 + src/backend/access/gist/gistget.c | 1 + src/backend/access/hash/hashsearch.c | 1 + src/backend/access/nbtree/nbtsearch.c | 1 + src/backend/access/spgist/spgscan.c | 1 + src/backend/utils/sort/tuplesort.c | 2 +- src/include/access/genam.h | 23 +-- src/include/executor/instrument_node.h | 211 +++++++++++++++++++++++++ src/include/nodes/execnodes.h | 140 ---------------- src/include/utils/tuplesort.h | 37 +---- 11 files changed, 220 insertions(+), 199 deletions(-) create mode 100644 src/include/executor/instrument_node.h diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c index 310e1c1a65c..0535d45f2d8 100644 --- a/contrib/bloom/blscan.c +++ b/contrib/bloom/blscan.c @@ -14,6 +14,7 @@ #include "access/relscan.h" #include "bloom.h" +#include "executor/instrument_node.h" #include "miscadmin.h" #include "pgstat.h" #include "storage/bufmgr.h" diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c index 47781028d6c..fb929761ab7 100644 --- a/src/backend/access/gin/ginscan.c +++ b/src/backend/access/gin/ginscan.c @@ -16,6 +16,7 @@ #include "access/gin_private.h" #include "access/relscan.h" +#include "executor/instrument_node.h" #include "pgstat.h" #include "utils/memutils.h" #include "utils/rel.h" diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index 6d05a5fdc34..ca0a397b7c3 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -17,6 +17,7 @@ #include "access/genam.h" #include "access/gist_private.h" #include "access/relscan.h" +#include "executor/instrument_node.h" #include "lib/pairingheap.h" #include "miscadmin.h" #include "pgstat.h" diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c index dfb0517b3b5..89d1c5bc6d7 100644 --- a/src/backend/access/hash/hashsearch.c +++ b/src/backend/access/hash/hashsearch.c @@ -17,6 +17,7 @@ #include "access/hash.h" #include "access/relscan.h" #include "miscadmin.h" +#include "executor/instrument_node.h" #include "pgstat.h" #include "storage/predicate.h" #include "utils/rel.h" diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 86b0f239e4b..32ae0bda892 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -18,6 +18,7 @@ #include "access/nbtree.h" #include "access/relscan.h" #include "access/xact.h" +#include "executor/instrument_node.h" #include "miscadmin.h" #include "pgstat.h" #include "storage/predicate.h" diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c index 967ba5f4e6a..2cc5f06f5d7 100644 --- a/src/backend/access/spgist/spgscan.c +++ b/src/backend/access/spgist/spgscan.c @@ -18,6 +18,7 @@ #include "access/genam.h" #include "access/relscan.h" #include "access/spgist_private.h" +#include "executor/instrument_node.h" #include "miscadmin.h" #include "pgstat.h" #include "storage/bufmgr.h" diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 473d31188b8..9e4cd816137 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -200,7 +200,7 @@ struct Tuplesortstate int64 maxSpace; /* maximum amount of space occupied among sort * of groups, either in-memory or on-disk */ bool isMaxSpaceDisk; /* true when maxSpace is value for on-disk - * space, false when its value for in-memory + * space, false when it's value for in-memory * space */ TupSortStatus maxSpaceStatus; /* sort status when maxSpace was reached */ LogicalTapeSet *tapeset; /* logtape.c object for tapes in a temp file */ diff --git a/src/include/access/genam.h b/src/include/access/genam.h index e37834c406d..4c0429cc613 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -17,6 +17,7 @@ #include "access/htup.h" #include "access/sdir.h" #include "access/skey.h" +#include "executor/instrument_node.h" #include "nodes/tidbitmap.h" #include "storage/buf.h" #include "storage/lockdefs.h" @@ -29,28 +30,6 @@ typedef struct TupleTableSlot TupleTableSlot; /* or relcache.h */ typedef struct RelationData *Relation; - -/* - * Struct for statistics maintained by amgettuple and amgetbitmap - * - * Note: IndexScanInstrumentation can't contain any pointers, since it is - * copied into a SharedIndexScanInstrumentation during parallel scans - */ -typedef struct IndexScanInstrumentation -{ - /* Index search count (incremented with pgstat_count_index_scan call) */ - uint64 nsearches; -} IndexScanInstrumentation; - -/* - * Struct for every worker's IndexScanInstrumentation, stored in shared memory - */ -typedef struct SharedIndexScanInstrumentation -{ - int num_workers; - IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER]; -} SharedIndexScanInstrumentation; - /* * Struct for statistics returned by ambuild */ diff --git a/src/include/executor/instrument_node.h b/src/include/executor/instrument_node.h new file mode 100644 index 00000000000..8847d7f94fa --- /dev/null +++ b/src/include/executor/instrument_node.h @@ -0,0 +1,211 @@ +/*------------------------------------------------------------------------- + * + * instrument_node.h + * Definitions for node-specific support for parallel query instrumentation + * + * These structs purposely contain no pointers because they are copied + * across processes during parallel query execution. Each worker copies its + * individual information into the container struct at executor shutdown time, + * to allow the leader to display the information in EXPLAIN ANALYZE. + * + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/instrument_node.h + * + *------------------------------------------------------------------------- + */ +#ifndef INSTRUMENT_NODE_H +#define INSTRUMENT_NODE_H + + +/* --------------------- + * Instrumentation information for aggregate function execution + * --------------------- + */ +typedef struct AggregateInstrumentation +{ + Size hash_mem_peak; /* peak hash table memory usage */ + uint64 hash_disk_used; /* kB of disk space used */ + int hash_batches_used; /* batches used during entire execution */ +} AggregateInstrumentation; + +/* + * Shared memory container for per-worker aggregate information + */ +typedef struct SharedAggInfo +{ + int num_workers; + AggregateInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedAggInfo; + + +/* --------------------- + * Instrumentation information for indexscans (amgettuple and amgetbitmap) + * --------------------- + */ +typedef struct IndexScanInstrumentation +{ + /* Index search count (incremented with pgstat_count_index_scan call) */ + uint64 nsearches; +} IndexScanInstrumentation; + +/* + * Shared memory container for per-worker information + */ +typedef struct SharedIndexScanInstrumentation +{ + int num_workers; + IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedIndexScanInstrumentation; + + +/* --------------------- + * Instrumentation information for bitmap heap scans + * + * exact_pages total number of exact pages retrieved + * lossy_pages total number of lossy pages retrieved + * --------------------- + */ +typedef struct BitmapHeapScanInstrumentation +{ + uint64 exact_pages; + uint64 lossy_pages; +} BitmapHeapScanInstrumentation; + +/* + * Shared memory container for per-worker information + */ +typedef struct SharedBitmapHeapInstrumentation +{ + int num_workers; + BitmapHeapScanInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedBitmapHeapInstrumentation; + + +/* --------------------- + * Instrumentation information for Memoize + * --------------------- + */ +typedef struct MemoizeInstrumentation +{ + uint64 cache_hits; /* number of rescans where we've found the + * scan parameters values to be cached */ + uint64 cache_misses; /* number of rescans where we've not found the + * scan parameters values to be cached */ + uint64 cache_evictions; /* number of cache entries removed due to + * the need to free memory */ + uint64 cache_overflows; /* number of times we've had to bypass the + * cache when filling it due to not being + * able to free enough space to store the + * current scan's tuples */ + uint64 mem_peak; /* peak memory usage in bytes */ +} MemoizeInstrumentation; + +/* + * Shared memory container for per-worker memoize information + */ +typedef struct SharedMemoizeInfo +{ + int num_workers; + MemoizeInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedMemoizeInfo; + + +/* --------------------- + * Instrumentation information for Sorts. + * --------------------- + */ + +typedef enum +{ + SORT_SPACE_TYPE_DISK, + SORT_SPACE_TYPE_MEMORY, +} TuplesortSpaceType; + +/* + * The parallel-sort infrastructure relies on having a zero TuplesortMethod + * to indicate that a worker never did anything, so we assign zero to + * SORT_TYPE_STILL_IN_PROGRESS. The other values of this enum can be + * OR'ed together to represent a situation where different workers used + * different methods, so we need a separate bit for each one. Keep the + * NUM_TUPLESORTMETHODS constant in sync with the number of bits! + */ +typedef enum +{ + SORT_TYPE_STILL_IN_PROGRESS = 0, + SORT_TYPE_TOP_N_HEAPSORT = 1 << 0, + SORT_TYPE_QUICKSORT = 1 << 1, + SORT_TYPE_EXTERNAL_SORT = 1 << 2, + SORT_TYPE_EXTERNAL_MERGE = 1 << 3, +} TuplesortMethod; +#define NUM_TUPLESORTMETHODS 4 + +typedef struct TuplesortInstrumentation +{ + TuplesortMethod sortMethod; /* sort algorithm used */ + TuplesortSpaceType spaceType; /* type of space spaceUsed represents */ + int64 spaceUsed; /* space consumption, in kB */ +} TuplesortInstrumentation; + +/* + * Shared memory container for per-worker sort information + */ +typedef struct SharedSortInfo +{ + int num_workers; + TuplesortInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedSortInfo; + + +/* --------------------- + * Instrumentation information for nodeHash.c + * --------------------- + */ +typedef struct HashInstrumentation +{ + int nbuckets; /* number of buckets at end of execution */ + int nbuckets_original; /* planned number of buckets */ + int nbatch; /* number of batches at end of execution */ + int nbatch_original; /* planned number of batches */ + Size space_peak; /* peak memory usage in bytes */ +} HashInstrumentation; + +/* + * Shared memory container for per-worker information + */ +typedef struct SharedHashInfo +{ + int num_workers; + HashInstrumentation hinstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedHashInfo; + + +/* --------------------- + * Instrumentation information for IncrementalSort + * --------------------- + */ +typedef struct IncrementalSortGroupInfo +{ + int64 groupCount; + int64 maxDiskSpaceUsed; + int64 totalDiskSpaceUsed; + int64 maxMemorySpaceUsed; + int64 totalMemorySpaceUsed; + bits32 sortMethods; /* bitmask of TuplesortMethod */ +} IncrementalSortGroupInfo; + +typedef struct IncrementalSortInfo +{ + IncrementalSortGroupInfo fullsortGroupInfo; + IncrementalSortGroupInfo prefixsortGroupInfo; +} IncrementalSortInfo; + +/* Shared memory container for per-worker incremental sort information */ +typedef struct SharedIncrementalSortInfo +{ + int num_workers; + IncrementalSortInfo sinfo[FLEXIBLE_ARRAY_MEMBER]; +} SharedIncrementalSortInfo; + +#endif /* INSTRUMENT_NODE_H */ diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 02265456978..6fd8b6bfc06 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1816,19 +1816,6 @@ typedef struct BitmapIndexScanState SharedIndexScanInstrumentation *biss_SharedInfo; } BitmapIndexScanState; -/* ---------------- - * BitmapHeapScanInstrumentation information - * - * exact_pages total number of exact pages retrieved - * lossy_pages total number of lossy pages retrieved - * ---------------- - */ -typedef struct BitmapHeapScanInstrumentation -{ - uint64 exact_pages; - uint64 lossy_pages; -} BitmapHeapScanInstrumentation; - /* ---------------- * SharedBitmapState information * @@ -1865,20 +1852,6 @@ typedef struct ParallelBitmapHeapState ConditionVariable cv; } ParallelBitmapHeapState; -/* ---------------- - * Instrumentation data for a parallel bitmap heap scan. - * - * A shared memory struct that each parallel worker copies its - * BitmapHeapScanInstrumentation information into at executor shutdown to - * allow the leader to display the information in EXPLAIN ANALYZE. - * ---------------- - */ -typedef struct SharedBitmapHeapInstrumentation -{ - int num_workers; - BitmapHeapScanInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; -} SharedBitmapHeapInstrumentation; - /* ---------------- * BitmapHeapScanState information * @@ -2305,31 +2278,6 @@ struct MemoizeEntry; struct MemoizeTuple; struct MemoizeKey; -typedef struct MemoizeInstrumentation -{ - uint64 cache_hits; /* number of rescans where we've found the - * scan parameter values to be cached */ - uint64 cache_misses; /* number of rescans where we've not found the - * scan parameter values to be cached. */ - uint64 cache_evictions; /* number of cache entries removed due to - * the need to free memory */ - uint64 cache_overflows; /* number of times we've had to bypass the - * cache when filling it due to not being - * able to free enough space to store the - * current scan's tuples. */ - uint64 mem_peak; /* peak memory usage in bytes */ -} MemoizeInstrumentation; - -/* ---------------- - * Shared memory container for per-worker memoize information - * ---------------- - */ -typedef struct SharedMemoizeInfo -{ - int num_workers; - MemoizeInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; -} SharedMemoizeInfo; - /* ---------------- * MemoizeState information * @@ -2385,16 +2333,6 @@ typedef struct PresortedKeyData OffsetNumber attno; /* attribute number in tuple */ } PresortedKeyData; -/* ---------------- - * Shared memory container for per-worker sort information - * ---------------- - */ -typedef struct SharedSortInfo -{ - int num_workers; - TuplesortInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; -} SharedSortInfo; - /* ---------------- * SortState information * ---------------- @@ -2414,40 +2352,6 @@ typedef struct SortState SharedSortInfo *shared_info; /* one entry per worker */ } SortState; -/* ---------------- - * Instrumentation information for IncrementalSort - * ---------------- - */ -typedef struct IncrementalSortGroupInfo -{ - int64 groupCount; - int64 maxDiskSpaceUsed; - int64 totalDiskSpaceUsed; - int64 maxMemorySpaceUsed; - int64 totalMemorySpaceUsed; - bits32 sortMethods; /* bitmask of TuplesortMethod */ -} IncrementalSortGroupInfo; - -typedef struct IncrementalSortInfo -{ - IncrementalSortGroupInfo fullsortGroupInfo; - IncrementalSortGroupInfo prefixsortGroupInfo; -} IncrementalSortInfo; - -/* ---------------- - * Shared memory container for per-worker incremental sort information - * ---------------- - */ -typedef struct SharedIncrementalSortInfo -{ - int num_workers; - IncrementalSortInfo sinfo[FLEXIBLE_ARRAY_MEMBER]; -} SharedIncrementalSortInfo; - -/* ---------------- - * IncrementalSortState information - * ---------------- - */ typedef enum { INCSORT_LOADFULLSORT, @@ -2490,27 +2394,6 @@ typedef struct GroupState bool grp_done; /* indicates completion of Group scan */ } GroupState; -/* --------------------- - * per-worker aggregate information - * --------------------- - */ -typedef struct AggregateInstrumentation -{ - Size hash_mem_peak; /* peak hash table memory usage */ - uint64 hash_disk_used; /* kB of disk space used */ - int hash_batches_used; /* batches used during entire execution */ -} AggregateInstrumentation; - -/* ---------------- - * Shared memory container for per-worker aggregate information - * ---------------- - */ -typedef struct SharedAggInfo -{ - int num_workers; - AggregateInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; -} SharedAggInfo; - /* --------------------- * AggState information * @@ -2787,29 +2670,6 @@ typedef struct GatherMergeState struct binaryheap *gm_heap; /* binary heap of slot indices */ } GatherMergeState; -/* ---------------- - * Values displayed by EXPLAIN ANALYZE - * ---------------- - */ -typedef struct HashInstrumentation -{ - int nbuckets; /* number of buckets at end of execution */ - int nbuckets_original; /* planned number of buckets */ - int nbatch; /* number of batches at end of execution */ - int nbatch_original; /* planned number of batches */ - Size space_peak; /* peak memory usage in bytes */ -} HashInstrumentation; - -/* ---------------- - * Shared memory container for per-worker hash information - * ---------------- - */ -typedef struct SharedHashInfo -{ - int num_workers; - HashInstrumentation hinstrument[FLEXIBLE_ARRAY_MEMBER]; -} SharedHashInfo; - /* ---------------- * HashState information * ---------------- diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h index 0a156bce44d..943a2b7dc93 100644 --- a/src/include/utils/tuplesort.h +++ b/src/include/utils/tuplesort.h @@ -24,6 +24,7 @@ #include "access/brin_tuple.h" #include "access/gin_tuple.h" #include "access/itup.h" +#include "executor/instrument_node.h" #include "executor/tuptable.h" #include "storage/dsm.h" #include "utils/logtape.h" @@ -61,35 +62,6 @@ typedef struct SortCoordinateData typedef struct SortCoordinateData *SortCoordinate; -/* - * Data structures for reporting sort statistics. Note that - * TuplesortInstrumentation can't contain any pointers because we - * sometimes put it in shared memory. - * - * The parallel-sort infrastructure relies on having a zero TuplesortMethod - * to indicate that a worker never did anything, so we assign zero to - * SORT_TYPE_STILL_IN_PROGRESS. The other values of this enum can be - * OR'ed together to represent a situation where different workers used - * different methods, so we need a separate bit for each one. Keep the - * NUM_TUPLESORTMETHODS constant in sync with the number of bits! - */ -typedef enum -{ - SORT_TYPE_STILL_IN_PROGRESS = 0, - SORT_TYPE_TOP_N_HEAPSORT = 1 << 0, - SORT_TYPE_QUICKSORT = 1 << 1, - SORT_TYPE_EXTERNAL_SORT = 1 << 2, - SORT_TYPE_EXTERNAL_MERGE = 1 << 3, -} TuplesortMethod; - -#define NUM_TUPLESORTMETHODS 4 - -typedef enum -{ - SORT_SPACE_TYPE_DISK, - SORT_SPACE_TYPE_MEMORY, -} TuplesortSpaceType; - /* Bitwise option flags for tuple sorts */ #define TUPLESORT_NONE 0 @@ -108,13 +80,6 @@ typedef enum */ #define TupleSortUseBumpTupleCxt(opt) (((opt) & TUPLESORT_ALLOWBOUNDED) == 0) -typedef struct TuplesortInstrumentation -{ - TuplesortMethod sortMethod; /* sort algorithm used */ - TuplesortSpaceType spaceType; /* type of space spaceUsed represents */ - int64 spaceUsed; /* space consumption, in kB */ -} TuplesortInstrumentation; - /* * The objects we actually sort are SortTuple structs. These contain * a pointer to the tuple proper (might be a MinimalTuple or IndexTuple),