Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdb6736c

Browse files
Fix memory leak in indexUnchanged hint mechanism.
Commit9dc718b added a "logically unchanged by UPDATE" hintingmechanism, which is currently used within nbtree indexes only (seecommitd168b66). This mechanism determined whether or not the incomingitem is a logically unchanged duplicate (a duplicate needed only forMVCC versioning purposes) once per row updated per non-HOT update. Thisapproach led to memory leaks which were noticeable with an UPDATEstatement that updated sufficiently many rows, at least on tables thathappen to have an expression index.On HEAD, fix the issue by adding a cache to the executor's per-indexIndexInfo struct.Take a different approach on Postgres 14 to avoid an ABI break: simplypass down the hint to all indexes unconditionally with non-HOT UPDATEs.This is deemed acceptable because the hint is currently interpretedwithin btinsert() as "perform a bottom-up index deletion pass if andwhen the only alternative is splitting the leaf page -- prefer to deleteany LP_DEAD-set items first". nbtree must always treat the hint as anoisy signal about what might work, as a strategy of last resort, withcosts imposed on non-HOT updaters. (The same thing might not be truewithin another index AM that applies the hint, which is why the originalbehavior is preserved on HEAD.)Author: Peter Geoghegan <pg@bowt.ie>Reported-By: Klaudie Willis <Klaudie.Willis@protonmail.com>Diagnosed-By: Tom Lane <tgl@sss.pgh.pa.us>Discussion:https://postgr.es/m/261065.1639497535@sss.pgh.pa.usBackpatch: 14-, where the hinting mechanism was added.
1 parente9b873f commitdb6736c

File tree

4 files changed

+37
-2
lines changed

4 files changed

+37
-2
lines changed

‎src/backend/catalog/toasting.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
302302
indexInfo->ii_OpclassOptions=NULL;
303303
indexInfo->ii_Unique= true;
304304
indexInfo->ii_ReadyForInserts= true;
305+
indexInfo->ii_CheckedUnchanged= false;
306+
indexInfo->ii_IndexUnchanged= false;
305307
indexInfo->ii_Concurrent= false;
306308
indexInfo->ii_BrokenHotChain= false;
307309
indexInfo->ii_ParallelWorkers=0;

‎src/backend/executor/execIndexing.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -935,19 +935,32 @@ static bool
935935
index_unchanged_by_update(ResultRelInfo*resultRelInfo,EState*estate,
936936
IndexInfo*indexInfo,RelationindexRelation)
937937
{
938-
Bitmapset*updatedCols=ExecGetUpdatedCols(resultRelInfo,estate);
939-
Bitmapset*extraUpdatedCols=ExecGetExtraUpdatedCols(resultRelInfo,estate);
938+
Bitmapset*updatedCols;
939+
Bitmapset*extraUpdatedCols;
940940
Bitmapset*allUpdatedCols;
941941
boolhasexpression= false;
942942
List*idxExprs;
943943

944+
/*
945+
* Check cache first
946+
*/
947+
if (indexInfo->ii_CheckedUnchanged)
948+
returnindexInfo->ii_IndexUnchanged;
949+
indexInfo->ii_CheckedUnchanged= true;
950+
944951
/*
945952
* Check for indexed attribute overlap with updated columns.
946953
*
947954
* Only do this for key columns. A change to a non-key column within an
948955
* INCLUDE index should not be counted here. Non-key column values are
949956
* opaque payload state to the index AM, a little like an extra table TID.
957+
*
958+
* Note that row-level BEFORE triggers won't affect our behavior, since
959+
* they don't affect the updatedCols bitmaps generally. It doesn't seem
960+
* worth the trouble of checking which attributes were changed directly.
950961
*/
962+
updatedCols=ExecGetUpdatedCols(resultRelInfo,estate);
963+
extraUpdatedCols=ExecGetExtraUpdatedCols(resultRelInfo,estate);
951964
for (intattr=0;attr<indexInfo->ii_NumIndexKeyAttrs;attr++)
952965
{
953966
intkeycol=indexInfo->ii_IndexAttrNumbers[attr];
@@ -968,6 +981,7 @@ index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate,
968981
extraUpdatedCols))
969982
{
970983
/* Changed key column -- don't hint for this index */
984+
indexInfo->ii_IndexUnchanged= false;
971985
return false;
972986
}
973987
}
@@ -981,7 +995,10 @@ index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate,
981995
* shows that the index as a whole is logically unchanged by UPDATE.
982996
*/
983997
if (!hasexpression)
998+
{
999+
indexInfo->ii_IndexUnchanged= true;
9841000
return true;
1001+
}
9851002

9861003
/*
9871004
* Need to pass only one bms to expression_tree_walker helper function.
@@ -1008,8 +1025,18 @@ index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate,
10081025
bms_free(allUpdatedCols);
10091026

10101027
if (hasexpression)
1028+
{
1029+
indexInfo->ii_IndexUnchanged= false;
10111030
return false;
1031+
}
10121032

1033+
/*
1034+
* Deliberately don't consider index predicates. We should even give the
1035+
* hint when result rel's "updated tuple" has no corresponding index
1036+
* tuple, which is possible with a partial index (provided the usual
1037+
* conditions are met).
1038+
*/
1039+
indexInfo->ii_IndexUnchanged= true;
10131040
return true;
10141041
}
10151042

‎src/backend/nodes/makefuncs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,8 @@ makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions,
751751
Assert(n->ii_NumIndexKeyAttrs <=n->ii_NumIndexAttrs);
752752
n->ii_Unique=unique;
753753
n->ii_ReadyForInserts=isready;
754+
n->ii_CheckedUnchanged= false;
755+
n->ii_IndexUnchanged= false;
754756
n->ii_Concurrent=concurrent;
755757

756758
/* expressions */

‎src/include/nodes/execnodes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ typedef struct ExprState
142142
*Uniqueis it a unique index?
143143
*OpclassOptionsopclass-specific options, or NULL if none
144144
*ReadyForInsertsis it valid for inserts?
145+
*CheckedUnchangedIndexUnchanged status determined yet?
146+
*IndexUnchangedaminsert hint, cached for retail inserts
145147
*Concurrentare we doing a concurrent index build?
146148
*BrokenHotChaindid we detect any broken HOT chains?
147149
*ParallelWorkers# of workers requested (excludes leader)
@@ -172,6 +174,8 @@ typedef struct IndexInfo
172174
Datum*ii_OpclassOptions;/* array with one entry per column */
173175
boolii_Unique;
174176
boolii_ReadyForInserts;
177+
boolii_CheckedUnchanged;
178+
boolii_IndexUnchanged;
175179
boolii_Concurrent;
176180
boolii_BrokenHotChain;
177181
intii_ParallelWorkers;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp