0008_disable_warm_on_manyindex_update.patch
application/octet-stream
Filename: 0008_disable_warm_on_manyindex_update.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/heap/heapam.c | 24 | 1 |
| src/backend/utils/cache/relcache.c | 51 | 1 |
| src/include/utils/relcache.h | 1 | 0 |
| src/include/utils/rel.h | 2 | 0 |
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 5de683a..2b5d8d2 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -3712,6 +3712,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
Bitmapset *interesting_attrs;
Bitmapset *modified_attrs;
Bitmapset *notready_attrs;
+ List *indexattrsList;
ItemId lp;
HeapTupleData oldtup;
HeapTuple heaptup;
@@ -3786,6 +3787,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
notready_attrs = RelationGetIndexAttrBitmap(relation,
INDEX_ATTR_BITMAP_NOTREADY);
+ indexattrsList = RelationGetIndexAttrList(relation);
block = ItemPointerGetBlockNumber(otid);
buffer = ReadBuffer(relation, block);
@@ -4455,7 +4457,28 @@ l2:
!bms_overlap(modified_attrs, exprindx_attrs) &&
!bms_is_subset(hot_attrs, modified_attrs) &&
!bms_overlap(notready_attrs, modified_attrs))
- use_warm_update = true;
+ {
+ int num_indexes, num_updating_indexes;
+ ListCell *l;
+
+ /*
+ * Everything else is Ok. Now check if the update will require
+ * less than or equal to 50% index updates. Anything above
+ * that, we can just do a regular update and save on WARM
+ * cleanup cost.
+ */
+ num_indexes = list_length(indexattrsList);
+ num_updating_indexes = 0;
+ foreach (l, indexattrsList)
+ {
+ Bitmapset *b = (Bitmapset *) lfirst(l);
+ if (bms_overlap(b, modified_attrs))
+ num_updating_indexes++;
+ }
+
+ if ((double)num_updating_indexes/num_indexes <= 0.5)
+ use_warm_update = true;
+ }
}
}
else
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 4be2445..c7266d7 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -4852,6 +4852,7 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
Bitmapset *indxnotreadyattrs; /* columns in not ready indexes */
List *indexoidlist;
List *newindexoidlist;
+ List *indexattrsList;
Oid relpkindex;
Oid relreplindex;
ListCell *l;
@@ -4920,6 +4921,7 @@ restart:
pkindexattrs = NULL;
idindexattrs = NULL;
indxnotreadyattrs = NULL;
+ indexattrsList = NIL;
foreach(l, indexoidlist)
{
Oid indexOid = lfirst_oid(l);
@@ -4929,6 +4931,7 @@ restart:
bool isKey; /* candidate key */
bool isPK; /* primary key */
bool isIDKey; /* replica identity index */
+ Bitmapset *thisindexattrs = NULL;
indexDesc = index_open(indexOid, AccessShareLock);
@@ -4953,6 +4956,9 @@ restart:
if (attrnum != 0)
{
+ thisindexattrs = bms_add_member(thisindexattrs,
+ attrnum - FirstLowInvalidHeapAttributeNumber);
+
indexattrs = bms_add_member(indexattrs,
attrnum - FirstLowInvalidHeapAttributeNumber);
@@ -4985,6 +4991,7 @@ restart:
* and predicates too.
*/
indexattrs = bms_add_members(indexattrs, exprindexattrs);
+ thisindexattrs = bms_add_members(thisindexattrs, exprindexattrs);
if (!indexInfo->ii_ReadyForInserts)
indxnotreadyattrs = bms_add_members(indxnotreadyattrs,
@@ -4998,6 +5005,7 @@ restart:
if (!indexDesc->rd_amroutine->amrecheck)
supportswarm = false;
+ indexattrsList = lappend(indexattrsList, thisindexattrs);
index_close(indexDesc, AccessShareLock);
}
@@ -5026,7 +5034,7 @@ restart:
bms_free(pkindexattrs);
bms_free(idindexattrs);
bms_free(indexattrs);
-
+ list_free_deep(indexattrsList);
goto restart;
}
@@ -5046,6 +5054,8 @@ restart:
relation->rd_idattr = NULL;
bms_free(relation->rd_indxnotreadyattr);
relation->rd_indxnotreadyattr = NULL;
+ list_free_deep(relation->rd_indexattrsList);
+ relation->rd_indexattrsList = NIL;
/*
* Now save copies of the bitmaps in the relcache entry. We intentionally
@@ -5061,6 +5071,18 @@ restart:
relation->rd_exprindexattr = bms_copy(exprindexattrs);
relation->rd_indexattr = bms_copy(bms_union(indexattrs, exprindexattrs));
relation->rd_indxnotreadyattr = bms_copy(indxnotreadyattrs);
+
+ /*
+ * create a deep copy of the list, copying each bitmap in the
+ * CurrentMemoryContext.
+ */
+ foreach(l, indexattrsList)
+ {
+ Bitmapset *b = (Bitmapset *) lfirst(l);
+ relation->rd_indexattrsList = lappend(relation->rd_indexattrsList,
+ bms_copy(b));
+ }
+
MemoryContextSwitchTo(oldcxt);
/* We return our original working copy for caller to play with */
@@ -5085,6 +5107,34 @@ restart:
}
/*
+ * Get a list of bitmaps, where each bitmap contains a list of attributes used
+ * by one index.
+ *
+ * The actual information is computed in RelationGetIndexAttrBitmap, but
+ * currently the only consumer of this function calls it immediately after
+ * calling RelationGetIndexAttrBitmap, we should be fine. We don't expect any
+ * relcache invalidation to come between these two calls and hence don't expect
+ * the cached information to change underneath.
+ */
+List *
+RelationGetIndexAttrList(Relation relation)
+{
+ ListCell *l;
+ List *indexattrsList = NIL;
+
+ /*
+ * Create a deep copy of the list by copying bitmaps in the
+ * CurrentMemoryContext.
+ */
+ foreach(l, relation->rd_indexattrsList)
+ {
+ Bitmapset *b = (Bitmapset *) lfirst(l);
+ indexattrsList = lappend(indexattrsList, bms_copy(b));
+ }
+ return indexattrsList;
+}
+
+/*
* RelationGetExclusionInfo -- get info about index's exclusion constraint
*
* This should be called only for an index that is known to have an
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index cd1976a..4b173b5 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -149,6 +149,8 @@ typedef struct RelationData
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 */
+ List *rd_indexattrsList; /* List of bitmaps, describing list of
+ attributes for each index */
bool rd_supportswarm;/* True if the table can be WARM updated */
PublicationActions *rd_pubactions; /* publication actions */
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index d5b3072..06c0183 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -58,6 +58,7 @@ typedef enum IndexAttrBitmapKind
extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation,
IndexAttrBitmapKind keyAttrs);
+extern List *RelationGetIndexAttrList(Relation relation);
extern void RelationGetExclusionInfo(Relation indexRelation,
Oid **operators,