Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit aedd554

Browse files
committed
Fix CatalogTupleInsert/Update abstraction for case of shared indstate.
Add CatalogTupleInsertWithInfo and CatalogTupleUpdateWithInfo to let callers use the CatalogTupleXXX abstraction layer even in cases where we want to share the results of CatalogOpenIndexes across multiple inserts/updates for efficiency. This finishes the job begun in commit 2f5c9d9, by allowing some remaining simple_heap_insert/update calls to be replaced. The abstraction layer is now complete enough that we don't have to export CatalogIndexInsert at all anymore. Also, this fixes several places in which 2f5c9d9 introduced performance regressions by using retail CatalogTupleInsert or CatalogTupleUpdate even though the previous coding had been able to amortize CatalogOpenIndexes work across multiple tuples. A possible future improvement is to arrange for the indexing.c functions to cache the CatalogIndexState somewhere, maybe in the relcache, in which case we could get rid of CatalogTupleInsertWithInfo and CatalogTupleUpdateWithInfo again. But that's a task for another day. Discussion: https://postgr.es/m/27502.1485981379@sss.pgh.pa.us
1 parent ab02896 commit aedd554

File tree

7 files changed

+84
-42
lines changed

7 files changed

+84
-42
lines changed

src/backend/catalog/heap.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -586,9 +586,10 @@ CheckAttributeType(const char *attname,
586586
* attribute to insert (but we ignore attacl and attoptions, which are always
587587
* initialized to NULL).
588588
*
589-
* indstate is the index state for CatalogIndexInsert. It can be passed as
590-
* NULL, in which case we'll fetch the necessary info. (Don't do this when
591-
* inserting multiple attributes, because it's a tad more expensive.)
589+
* indstate is the index state for CatalogTupleInsertWithInfo. It can be
590+
* passed as NULL, in which case we'll fetch the necessary info. (Don't do
591+
* this when inserting multiple attributes, because it's a tad more
592+
* expensive.)
592593
*/
593594
void
594595
InsertPgAttributeTuple(Relation pg_attribute_rel,
@@ -630,18 +631,10 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
630631
tup = heap_form_tuple(RelationGetDescr(pg_attribute_rel), values, nulls);
631632

632633
/* finally insert the new tuple, update the indexes, and clean up */
633-
simple_heap_insert(pg_attribute_rel, tup);
634-
635634
if (indstate != NULL)
636-
CatalogIndexInsert(indstate, tup);
635+
CatalogTupleInsertWithInfo(pg_attribute_rel, tup, indstate);
637636
else
638-
{
639-
CatalogIndexState indstate;
640-
641-
indstate = CatalogOpenIndexes(pg_attribute_rel);
642-
CatalogIndexInsert(indstate, tup);
643-
CatalogCloseIndexes(indstate);
644-
}
637+
CatalogTupleInsert(pg_attribute_rel, tup);
645638

646639
heap_freetuple(tup);
647640
}

src/backend/catalog/indexing.c

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ CatalogCloseIndexes(CatalogIndexState indstate)
6868
*
6969
* This is effectively a cut-down version of ExecInsertIndexTuples.
7070
*/
71-
void
71+
static void
7272
CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
7373
{
7474
int i;
@@ -148,18 +148,20 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
148148
/*
149149
* CatalogTupleInsert - do heap and indexing work for a new catalog tuple
150150
*
151+
* Insert the tuple data in "tup" into the specified catalog relation.
152+
* The Oid of the inserted tuple is returned.
153+
*
151154
* This is a convenience routine for the common case of inserting a single
152155
* tuple in a system catalog; it inserts a new heap tuple, keeping indexes
153-
* current. Avoid using it for multiple tuples, since opening the indexes and
154-
* building the index info structures is moderately expensive.
155-
*
156-
* The Oid of the inserted tuple is returned.
156+
* current. Avoid using it for multiple tuples, since opening the indexes
157+
* and building the index info structures is moderately expensive.
158+
* (Use CatalogTupleInsertWithInfo in such cases.)
157159
*/
158160
Oid
159161
CatalogTupleInsert(Relation heapRel, HeapTuple tup)
160162
{
161163
CatalogIndexState indstate;
162-
Oid oid;
164+
Oid oid;
163165

164166
indstate = CatalogOpenIndexes(heapRel);
165167

@@ -171,14 +173,37 @@ CatalogTupleInsert(Relation heapRel, HeapTuple tup)
171173
return oid;
172174
}
173175

176+
/*
177+
* CatalogTupleInsertWithInfo - as above, but with caller-supplied index info
178+
*
179+
* This should be used when it's important to amortize CatalogOpenIndexes/
180+
* CatalogCloseIndexes work across multiple insertions. At some point we
181+
* might cache the CatalogIndexState data somewhere (perhaps in the relcache)
182+
* so that callers needn't trouble over this ... but we don't do so today.
183+
*/
184+
Oid
185+
CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup,
186+
CatalogIndexState indstate)
187+
{
188+
Oid oid;
189+
190+
oid = simple_heap_insert(heapRel, tup);
191+
192+
CatalogIndexInsert(indstate, tup);
193+
194+
return oid;
195+
}
196+
174197
/*
175198
* CatalogTupleUpdate - do heap and indexing work for updating a catalog tuple
176199
*
200+
* Update the tuple identified by "otid", replacing it with the data in "tup".
201+
*
177202
* This is a convenience routine for the common case of updating a single
178-
* tuple in a system catalog; it updates one heap tuple (identified by otid)
179-
* with tup, keeping indexes current. Avoid using it for multiple tuples,
180-
* since opening the indexes and building the index info structures is
181-
* moderately expensive.
203+
* tuple in a system catalog; it updates one heap tuple, keeping indexes
204+
* current. Avoid using it for multiple tuples, since opening the indexes
205+
* and building the index info structures is moderately expensive.
206+
* (Use CatalogTupleUpdateWithInfo in such cases.)
182207
*/
183208
void
184209
CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
@@ -193,15 +218,37 @@ CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
193218
CatalogCloseIndexes(indstate);
194219
}
195220

221+
/*
222+
* CatalogTupleUpdateWithInfo - as above, but with caller-supplied index info
223+
*
224+
* This should be used when it's important to amortize CatalogOpenIndexes/
225+
* CatalogCloseIndexes work across multiple updates. At some point we
226+
* might cache the CatalogIndexState data somewhere (perhaps in the relcache)
227+
* so that callers needn't trouble over this ... but we don't do so today.
228+
*/
229+
void
230+
CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup,
231+
CatalogIndexState indstate)
232+
{
233+
simple_heap_update(heapRel, otid, tup);
234+
235+
CatalogIndexInsert(indstate, tup);
236+
}
237+
196238
/*
197239
* CatalogTupleDelete - do heap and indexing work for deleting a catalog tuple
198240
*
199-
* Delete the tuple identified by tid in the specified catalog.
241+
* Delete the tuple identified by "tid" in the specified catalog.
200242
*
201243
* With Postgres heaps, there is no index work to do at deletion time;
202244
* cleanup will be done later by VACUUM. However, callers of this function
203245
* shouldn't have to know that; we'd like a uniform abstraction for all
204246
* catalog tuple changes. Hence, provide this currently-trivial wrapper.
247+
*
248+
* The abstraction is a bit leaky in that we don't provide an optimized
249+
* CatalogTupleDeleteWithInfo version, because there is currently nothing to
250+
* optimize. If we ever need that, rather than touching a lot of call sites,
251+
* it might be better to do something about caching CatalogIndexState.
205252
*/
206253
void
207254
CatalogTupleDelete(Relation heapRel, ItemPointer tid)

src/backend/catalog/pg_depend.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,11 @@ recordMultipleDependencies(const ObjectAddress *depender,
107107

108108
tup = heap_form_tuple(dependDesc->rd_att, values, nulls);
109109

110-
simple_heap_insert(dependDesc, tup);
111-
112-
/* keep indexes current */
110+
/* fetch index info only when we know we need it */
113111
if (indstate == NULL)
114112
indstate = CatalogOpenIndexes(dependDesc);
115113

116-
CatalogIndexInsert(indstate, tup);
114+
CatalogTupleInsertWithInfo(dependDesc, tup, indstate);
117115

118116
heap_freetuple(tup);
119117
}

src/backend/catalog/pg_shdepend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
753753
HeapTuple newtup;
754754

755755
newtup = heap_modify_tuple(tup, sdepDesc, values, nulls, replace);
756-
CatalogTupleInsert(sdepRel, newtup);
756+
CatalogTupleInsertWithInfo(sdepRel, newtup, indstate);
757757

758758
heap_freetuple(newtup);
759759
}

src/backend/commands/cluster.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,6 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
11411141
relfilenode2;
11421142
Oid swaptemp;
11431143
char swptmpchr;
1144-
CatalogIndexState indstate;
11451144

11461145
/* We need writable copies of both pg_class tuples. */
11471146
relRelation = heap_open(RelationRelationId, RowExclusiveLock);
@@ -1285,13 +1284,13 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
12851284
*/
12861285
if (!target_is_pg_class)
12871286
{
1288-
simple_heap_update(relRelation, &reltup1->t_self, reltup1);
1289-
simple_heap_update(relRelation, &reltup2->t_self, reltup2);
1287+
CatalogIndexState indstate;
12901288

1291-
/* Keep system catalogs current */
12921289
indstate = CatalogOpenIndexes(relRelation);
1293-
CatalogIndexInsert(indstate, reltup1);
1294-
CatalogIndexInsert(indstate, reltup2);
1290+
CatalogTupleUpdateWithInfo(relRelation, &reltup1->t_self, reltup1,
1291+
indstate);
1292+
CatalogTupleUpdateWithInfo(relRelation, &reltup2->t_self, reltup2,
1293+
indstate);
12951294
CatalogCloseIndexes(indstate);
12961295
}
12971296
else

src/backend/storage/large_object/inv_api.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,8 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
678678
replace[Anum_pg_largeobject_data - 1] = true;
679679
newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
680680
values, nulls, replace);
681-
CatalogTupleUpdate(lo_heap_r, &newtup->t_self, newtup);
681+
CatalogTupleUpdateWithInfo(lo_heap_r, &newtup->t_self, newtup,
682+
indstate);
682683
heap_freetuple(newtup);
683684

684685
/*
@@ -720,7 +721,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
720721
values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
721722
values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
722723
newtup = heap_form_tuple(lo_heap_r->rd_att, values, nulls);
723-
CatalogTupleInsert(lo_heap_r, newtup);
724+
CatalogTupleInsertWithInfo(lo_heap_r, newtup, indstate);
724725
heap_freetuple(newtup);
725726
}
726727
pageno++;
@@ -848,7 +849,8 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
848849
replace[Anum_pg_largeobject_data - 1] = true;
849850
newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
850851
values, nulls, replace);
851-
CatalogTupleUpdate(lo_heap_r, &newtup->t_self, newtup);
852+
CatalogTupleUpdateWithInfo(lo_heap_r, &newtup->t_self, newtup,
853+
indstate);
852854
heap_freetuple(newtup);
853855
}
854856
else
@@ -885,7 +887,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
885887
values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
886888
values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
887889
newtup = heap_form_tuple(lo_heap_r->rd_att, values, nulls);
888-
CatalogTupleInsert(lo_heap_r, newtup);
890+
CatalogTupleInsertWithInfo(lo_heap_r, newtup, indstate);
889891
heap_freetuple(newtup);
890892
}
891893

src/include/catalog/indexing.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ typedef struct ResultRelInfo *CatalogIndexState;
3030
*/
3131
extern CatalogIndexState CatalogOpenIndexes(Relation heapRel);
3232
extern void CatalogCloseIndexes(CatalogIndexState indstate);
33-
extern void CatalogIndexInsert(CatalogIndexState indstate,
34-
HeapTuple heapTuple);
35-
extern Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup);
33+
extern Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup);
34+
extern Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup,
35+
CatalogIndexState indstate);
3636
extern void CatalogTupleUpdate(Relation heapRel, ItemPointer otid,
3737
HeapTuple tup);
38+
extern void CatalogTupleUpdateWithInfo(Relation heapRel,
39+
ItemPointer otid, HeapTuple tup,
40+
CatalogIndexState indstate);
3841
extern void CatalogTupleDelete(Relation heapRel, ItemPointer tid);
3942

4043

0 commit comments

Comments
 (0)