diff options
author | Tomas Vondra <tomas.vondra@postgresql.org> | 2023-03-20 10:34:07 +0100 |
---|---|---|
committer | Tomas Vondra <tomas.vondra@postgresql.org> | 2023-03-20 11:02:42 +0100 |
commit | 19d8e2308bc51ec4ab993ce90077342c915dd116 (patch) | |
tree | 80742287fd696662b892802b6ced26e93e7d68fb /src/include | |
parent | e8583126833a53f4eebe28a8de45d128f01ff664 (diff) | |
download | postgresql-19d8e2308bc51ec4ab993ce90077342c915dd116.tar.gz postgresql-19d8e2308bc51ec4ab993ce90077342c915dd116.zip |
Ignore BRIN indexes when checking for HOT updates
When determining whether an index update may be skipped by using HOT, we
can ignore attributes indexed by block summarizing indexes without
references to individual tuples that need to be cleaned up.
A new type TU_UpdateIndexes provides a signal to the executor to
determine which indexes to update - no indexes, all indexes, or only the
summarizing indexes.
This also removes rd_indexattr list, and replaces it with rd_attrsvalid
flag. The list was not used anywhere, and a simple flag is sufficient.
This was originally committed as 5753d4ee32, but then got reverted by
e3fcca0d0d because of correctness issues.
Original patch by Josef Simanek, various fixes and improvements by Tomas
Vondra and me.
Authors: Matthias van de Meent, Josef Simanek, Tomas Vondra
Reviewed-by: Tomas Vondra, Alvaro Herrera
Discussion: https://postgr.es/m/05ebcb44-f383-86e3-4f31-0a97a55634cf@enterprisedb.com
Discussion: https://postgr.es/m/CAFp7QwpMRGcDAQumN7onN9HjrJ3u4X3ZRXdGFT0K5G2JWvnbWg%40mail.gmail.com
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/access/amapi.h | 2 | ||||
-rw-r--r-- | src/include/access/heapam.h | 5 | ||||
-rw-r--r-- | src/include/access/tableam.h | 22 | ||||
-rw-r--r-- | src/include/executor/executor.h | 3 | ||||
-rw-r--r-- | src/include/nodes/execnodes.h | 2 | ||||
-rw-r--r-- | src/include/nodes/makefuncs.h | 4 | ||||
-rw-r--r-- | src/include/utils/rel.h | 4 | ||||
-rw-r--r-- | src/include/utils/relcache.h | 5 |
8 files changed, 37 insertions, 10 deletions
diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h index 4f1f67b4d03..281039ef673 100644 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@ -244,6 +244,8 @@ typedef struct IndexAmRoutine bool amcaninclude; /* does AM use maintenance_work_mem? */ bool amusemaintenanceworkmem; + /* does AM store tuple information only at block granularity? */ + bool amsummarizing; /* OR of parallel vacuum flags. See vacuum.h for flags. */ uint8 amparallelvacuumoptions; /* type of data stored in index, or InvalidOid if variable */ diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 8d74d1b7e30..faf50265191 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -249,7 +249,8 @@ extern void heap_abort_speculative(Relation relation, ItemPointer tid); extern TM_Result heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, CommandId cid, Snapshot crosscheck, bool wait, - struct TM_FailureData *tmfd, LockTupleMode *lockmode); + struct TM_FailureData *tmfd, LockTupleMode *lockmode, + TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, bool follow_updates, @@ -275,7 +276,7 @@ extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple); extern void simple_heap_insert(Relation relation, HeapTuple tup); extern void simple_heap_delete(Relation relation, ItemPointer tid); extern void simple_heap_update(Relation relation, ItemPointer otid, - HeapTuple tup); + HeapTuple tup, TU_UpdateIndexes *update_indexes); extern TransactionId heap_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate); diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 652e96f1b0b..50ae053f461 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -103,6 +103,22 @@ typedef enum TM_Result } TM_Result; /* + * Result codes for table_update(..., update_indexes*..). + * Used to determine which indexes to update. + */ +typedef enum TU_UpdateIndexes +{ + /* No indexed columns were updated (incl. TID addressing of tuple) */ + TU_None, + + /* A non-summarizing indexed column was updated, or the TID has changed */ + TU_All, + + /* Only summarized columns were updated, TID is unchanged */ + TU_Summarizing +} TU_UpdateIndexes; + +/* * When table_tuple_update, table_tuple_delete, or table_tuple_lock fail * because the target tuple is already outdated, they fill in this struct to * provide information to the caller about what happened. @@ -526,7 +542,7 @@ typedef struct TableAmRoutine bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, - bool *update_indexes); + TU_UpdateIndexes *update_indexes); /* see table_tuple_lock() for reference about parameters */ TM_Result (*tuple_lock) (Relation rel, @@ -1514,7 +1530,7 @@ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, - bool *update_indexes) + TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, cid, snapshot, crosscheck, @@ -2038,7 +2054,7 @@ extern void simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot); extern void simple_table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, Snapshot snapshot, - bool *update_indexes); + TU_UpdateIndexes *update_indexes); /* ---------------------------------------------------------------------------- diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 946abc0051c..dbd77050c7d 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -620,7 +620,8 @@ extern List *ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool update, bool noDupErr, - bool *specConflict, List *arbiterIndexes); + bool *specConflict, List *arbiterIndexes, + bool onlySummarizing); extern bool ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, ItemPointer conflictTid, diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index bc67cb9ed82..d97f5a8e7dc 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -161,6 +161,7 @@ typedef struct ExprState * IndexUnchanged aminsert hint, cached for retail inserts * Concurrent are we doing a concurrent index build? * BrokenHotChain did we detect any broken HOT chains? + * Summarizing is it a summarizing index? * ParallelWorkers # of workers requested (excludes leader) * Am Oid of index AM * AmCache private cache area for index AM @@ -194,6 +195,7 @@ typedef struct IndexInfo bool ii_IndexUnchanged; bool ii_Concurrent; bool ii_BrokenHotChain; + bool ii_Summarizing; int ii_ParallelWorkers; Oid ii_Am; void *ii_AmCache; diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index 80f1d5336bb..64651c9b00b 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -96,7 +96,9 @@ extern List *make_ands_implicit(Expr *clause); extern IndexInfo *makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions, List *predicates, - bool unique, bool nulls_not_distinct, bool isready, bool concurrent); + bool unique, bool nulls_not_distinct, + bool isready, bool concurrent, + bool summarizing); extern DefElem *makeDefElem(char *name, Node *arg, int location); extern DefElem *makeDefElemExtended(char *nameSpace, char *name, Node *arg, diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 67f994cb3e2..c0ddddb2f0d 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -156,10 +156,12 @@ typedef struct RelationData List *rd_statlist; /* list of OIDs of extended stats */ /* data managed by RelationGetIndexAttrBitmap: */ - Bitmapset *rd_indexattr; /* identifies columns used in indexes */ + bool rd_attrsvalid; /* are bitmaps of attrs valid? */ Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */ Bitmapset *rd_pkattr; /* cols included in primary key */ Bitmapset *rd_idattr; /* included in replica identity index */ + Bitmapset *rd_hotblockingattr; /* cols blocking HOT update */ + Bitmapset *rd_summarizedattr; /* cols indexed by summarizing indexes */ PublicationDesc *rd_pubdesc; /* publication descriptor, or NULL */ diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index 88460f21c56..beeb28b83cb 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -56,10 +56,11 @@ extern bytea **RelationGetIndexAttOptions(Relation relation, bool copy); typedef enum IndexAttrBitmapKind { - INDEX_ATTR_BITMAP_ALL, INDEX_ATTR_BITMAP_KEY, INDEX_ATTR_BITMAP_PRIMARY_KEY, - INDEX_ATTR_BITMAP_IDENTITY_KEY + INDEX_ATTR_BITMAP_IDENTITY_KEY, + INDEX_ATTR_BITMAP_HOT_BLOCKING, + INDEX_ATTR_BITMAP_SUMMARIZED } IndexAttrBitmapKind; extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation, |