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

Commitd03a933

Browse files
committed
Fix performance problems with pg_index lookups (see, for example,
discussion of 5/19/00). pg_index is now searched for indexes of arelation using an indexscan. Moreover, this is done once and cachedin the relcache entry for the relation, in the form of a list of OIDsfor the indexes. This list is used by the parser and executor to drivelookups in the pg_index syscache when they want to know the propertiesof the indexes. Net result: index information will be fully cachedfor repetitive operations such as inserts.
1 parent9cf80f2 commitd03a933

File tree

13 files changed

+384
-520
lines changed

13 files changed

+384
-520
lines changed

‎src/backend/catalog/index.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.116 2000/06/1704:56:36 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.117 2000/06/1721:48:39 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -1105,6 +1105,7 @@ index_create(char *heapRelationName,
11051105
void
11061106
index_drop(OidindexId)
11071107
{
1108+
OidheapId;
11081109
RelationuserHeapRelation;
11091110
RelationuserIndexRelation;
11101111
RelationindexRelation;
@@ -1125,8 +1126,8 @@ index_drop(Oid indexId)
11251126
*else other backends will still see this index in pg_index.
11261127
* ----------------
11271128
*/
1128-
userHeapRelation=heap_open(IndexGetRelation(indexId),
1129-
AccessExclusiveLock);
1129+
heapId=IndexGetRelation(indexId);
1130+
userHeapRelation=heap_open(heapId,AccessExclusiveLock);
11301131

11311132
userIndexRelation=index_open(indexId);
11321133
LockRelation(userIndexRelation,AccessExclusiveLock);
@@ -1158,6 +1159,7 @@ index_drop(Oid indexId)
11581159
*/
11591160
relationRelation=heap_openr(RelationRelationName,RowExclusiveLock);
11601161

1162+
/* Remove the pg_class tuple for the index itself */
11611163
tuple=SearchSysCacheTupleCopy(RELOID,
11621164
ObjectIdGetDatum(indexId),
11631165
0,0,0);
@@ -1166,6 +1168,23 @@ index_drop(Oid indexId)
11661168

11671169
heap_delete(relationRelation,&tuple->t_self,NULL);
11681170
heap_freetuple(tuple);
1171+
1172+
/*
1173+
* Find the pg_class tuple for the owning relation. We do not attempt
1174+
* to clear relhasindex, since we are too lazy to test whether any other
1175+
* indexes remain (the next VACUUM will fix it if necessary). But we
1176+
* must send out a shared-cache-inval notice on the owning relation
1177+
* to ensure other backends update their relcache lists of indexes.
1178+
*/
1179+
tuple=SearchSysCacheTupleCopy(RELOID,
1180+
ObjectIdGetDatum(heapId),
1181+
0,0,0);
1182+
1183+
Assert(HeapTupleIsValid(tuple));
1184+
1185+
ImmediateInvalidateSharedHeapTuple(relationRelation,tuple);
1186+
heap_freetuple(tuple);
1187+
11691188
heap_close(relationRelation,RowExclusiveLock);
11701189

11711190
/* ----------------
@@ -1447,9 +1466,6 @@ setRelhasindexInplace(Oid relid, bool hasindex, bool immediate)
14471466
*/
14481467
if (pg_class_scan)
14491468
{
1450-
1451-
if (!IsBootstrapProcessingMode())
1452-
ImmediateInvalidateSharedHeapTuple(pg_class,tuple);
14531469
rd_rel= (Form_pg_class)GETSTRUCT(tuple);
14541470
rd_rel->relhasindex=hasindex;
14551471
WriteNoReleaseBuffer(pg_class_scan->rs_cbuf);
@@ -1461,12 +1477,18 @@ setRelhasindexInplace(Oid relid, bool hasindex, bool immediate)
14611477

14621478
htup.t_self=tuple->t_self;
14631479
heap_fetch(pg_class,SnapshotNow,&htup,&buffer);
1464-
ImmediateInvalidateSharedHeapTuple(pg_class,tuple);
14651480
rd_rel= (Form_pg_class)GETSTRUCT(&htup);
14661481
rd_rel->relhasindex=hasindex;
14671482
WriteBuffer(buffer);
14681483
}
14691484

1485+
/*
1486+
* Send out a shared-cache-inval message so other backends notice the
1487+
* update and fix their syscaches/relcaches.
1488+
*/
1489+
if (!IsBootstrapProcessingMode())
1490+
ImmediateInvalidateSharedHeapTuple(pg_class,tuple);
1491+
14701492
if (!pg_class_scan)
14711493
heap_freetuple(tuple);
14721494
else

‎src/backend/commands/copy.c

Lines changed: 24 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.114 2000/06/15 03:32:07 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.115 2000/06/17 21:48:42 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -32,6 +32,7 @@
3232
#include"tcop/tcopprot.h"
3333
#include"utils/acl.h"
3434
#include"utils/builtins.h"
35+
#include"utils/relcache.h"
3536
#include"utils/syscache.h"
3637

3738
#ifdefMULTIBYTE
@@ -1081,78 +1082,43 @@ IsTypeByVal(Oid type)
10811082
* Space for the array itself is palloc'ed.
10821083
*/
10831084

1084-
typedefstructrel_list
1085-
{
1086-
Oidindex_rel_oid;
1087-
structrel_list*next;
1088-
}RelationList;
1089-
10901085
staticvoid
10911086
GetIndexRelations(Oidmain_relation_oid,
10921087
int*n_indices,
10931088
Relation**index_rels)
10941089
{
1095-
RelationList*head,
1096-
*scan;
1097-
Relationpg_index_rel;
1098-
HeapScanDescscandesc;
1099-
Oidindex_relation_oid;
1100-
HeapTupletuple;
1101-
TupleDesctupDesc;
1090+
Relationrelation;
1091+
List*indexoidlist,
1092+
*indexoidscan;
11021093
inti;
1103-
boolisnull;
11041094

1105-
pg_index_rel=heap_openr(IndexRelationName,AccessShareLock);
1106-
scandesc=heap_beginscan(pg_index_rel,0,SnapshotNow,0,NULL);
1107-
tupDesc=RelationGetDescr(pg_index_rel);
1095+
relation=heap_open(main_relation_oid,AccessShareLock);
1096+
indexoidlist=RelationGetIndexList(relation);
11081097

1109-
*n_indices=0;
1098+
*n_indices=length(indexoidlist);
11101099

1111-
head= (RelationList*)palloc(sizeof(RelationList));
1112-
scan=head;
1113-
head->next=NULL;
1100+
if (*n_indices>0)
1101+
*index_rels= (Relation*)palloc(*n_indices*sizeof(Relation));
1102+
else
1103+
*index_rels=NULL;
11141104

1115-
while (HeapTupleIsValid(tuple=heap_getnext(scandesc,0)))
1105+
i=0;
1106+
foreach(indexoidscan,indexoidlist)
11161107
{
1108+
Oidindexoid=lfirsti(indexoidscan);
1109+
Relationindex=index_open(indexoid);
11171110

1118-
index_relation_oid= (Oid)DatumGetInt32(heap_getattr(tuple,2,
1119-
tupDesc,&isnull));
1120-
if (index_relation_oid==main_relation_oid)
1121-
{
1122-
scan->index_rel_oid= (Oid)DatumGetInt32(heap_getattr(tuple,
1123-
Anum_pg_index_indexrelid,
1124-
tupDesc,&isnull));
1125-
(*n_indices)++;
1126-
scan->next= (RelationList*)palloc(sizeof(RelationList));
1127-
scan=scan->next;
1128-
}
1129-
}
1130-
1131-
heap_endscan(scandesc);
1132-
heap_close(pg_index_rel,AccessShareLock);
1133-
1134-
/* We cannot trust to relhasindex of the main_relation now, so... */
1135-
if (*n_indices==0)
1136-
return;
1137-
1138-
*index_rels= (Relation*)palloc(*n_indices*sizeof(Relation));
1139-
1140-
for (i=0,scan=head;i<*n_indices;i++,scan=scan->next)
1141-
{
1142-
(*index_rels)[i]=index_open(scan->index_rel_oid);
11431111
/* see comments in ExecOpenIndices() in execUtils.c */
1144-
if ((*index_rels)[i]!=NULL&&
1145-
((*index_rels)[i])->rd_rel->relam!=BTREE_AM_OID&&
1146-
((*index_rels)[i])->rd_rel->relam!=HASH_AM_OID)
1147-
LockRelation((*index_rels)[i],AccessExclusiveLock);
1112+
if (index!=NULL&&
1113+
index->rd_rel->relam!=BTREE_AM_OID&&
1114+
index->rd_rel->relam!=HASH_AM_OID)
1115+
LockRelation(index,AccessExclusiveLock);
1116+
(*index_rels)[i]=index;
1117+
i++;
11481118
}
11491119

1150-
for (i=0,scan=head;i<*n_indices+1;i++)
1151-
{
1152-
scan=head->next;
1153-
pfree(head);
1154-
head=scan;
1155-
}
1120+
freeList(indexoidlist);
1121+
heap_close(relation,AccessShareLock);
11561122
}
11571123

11581124
/*

‎src/backend/commands/indexcmds.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.29 2000/06/15 03:32:07 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.30 2000/06/17 21:48:42 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -221,6 +221,13 @@ DefineIndex(char *heapRelationName,
221221
lossy,unique,primary);
222222
}
223223

224+
/*
225+
* We update the relation's pg_class tuple even if it already has
226+
* relhasindex = true. This is needed to cause a shared-cache-inval
227+
* message to be sent for the pg_class tuple, which will cause other
228+
* backends to flush their relcache entries and in particular their
229+
* cached lists of the indexes for this relation.
230+
*/
224231
setRelhasindexInplace(relationId, true, false);
225232
}
226233

‎src/backend/commands/vacuum.c

Lines changed: 20 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.159 2000/05/29 17:40:43momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.160 2000/06/17 21:48:43tgl Exp $
1212
*
1313
1414
*-------------------------------------------------------------------------
@@ -72,7 +72,7 @@ static void update_relstats(Oid relid, int num_pages, int num_tuples, bool hasin
7272
staticVacPagetid_reaped(ItemPointeritemptr,VacPageListvacpagelist);
7373
staticvoidreap_page(VacPageListvacpagelist,VacPagevacpage);
7474
staticvoidvpage_insert(VacPageListvacpagelist,VacPagevpnew);
75-
staticvoidget_indices(Oidrelid,int*nindices,Relation**Irel);
75+
staticvoidget_indices(Relationrelation,int*nindices,Relation**Irel);
7676
staticvoidclose_indices(intnindices,Relation*Irel);
7777
staticvoidget_index_desc(Relationonerel,intnindices,Relation*Irel,IndDesc**Idesc);
7878
staticvoid*vac_find_eq(void*bot,intnelem,intsize,void*elm,
@@ -416,7 +416,7 @@ vacuum_rel(Oid relid, bool analyze)
416416
/* Now open indices */
417417
nindices=0;
418418
Irel= (Relation*)NULL;
419-
get_indices(vacrelstats->relid,&nindices,&Irel);
419+
get_indices(onerel,&nindices,&Irel);
420420
if (!Irel)
421421
reindex= false;
422422
elseif (!RelationGetForm(onerel)->relhasindex)
@@ -2331,80 +2331,33 @@ CommonSpecialPortalIsOpen(void)
23312331
returnCommonSpecialPortalInUse;
23322332
}
23332333

2334+
23342335
staticvoid
2335-
get_indices(Oidrelid,int*nindices,Relation**Irel)
2336+
get_indices(Relationrelation,int*nindices,Relation**Irel)
23362337
{
2337-
Relationpgindex;
2338-
Relationirel;
2339-
TupleDesctupdesc;
2340-
HeapTupletuple;
2341-
HeapScanDescscan;
2342-
Datumd;
2343-
inti,
2344-
k;
2345-
booln;
2346-
ScanKeyDatakey;
2347-
Oid*ioid;
2348-
2349-
*nindices=i=0;
2350-
2351-
ioid= (Oid*)palloc(10*sizeof(Oid));
2352-
2353-
/* prepare a heap scan on the pg_index relation */
2354-
pgindex=heap_openr(IndexRelationName,AccessShareLock);
2355-
tupdesc=RelationGetDescr(pgindex);
2356-
2357-
ScanKeyEntryInitialize(&key,0x0,Anum_pg_index_indrelid,
2358-
F_OIDEQ,
2359-
ObjectIdGetDatum(relid));
2360-
2361-
scan=heap_beginscan(pgindex, false,SnapshotNow,1,&key);
2362-
2363-
while (HeapTupleIsValid(tuple=heap_getnext(scan,0)))
2364-
{
2365-
d=heap_getattr(tuple,Anum_pg_index_indexrelid,
2366-
tupdesc,&n);
2367-
i++;
2368-
if (i %10==0)
2369-
ioid= (Oid*)repalloc(ioid, (i+10)*sizeof(Oid));
2370-
ioid[i-1]=DatumGetObjectId(d);
2371-
}
2338+
List*indexoidlist,
2339+
*indexoidscan;
2340+
inti;
23722341

2373-
heap_endscan(scan);
2374-
heap_close(pgindex,AccessShareLock);
2342+
indexoidlist=RelationGetIndexList(relation);
23752343

2376-
if (i==0)
2377-
{/* No one index found */
2378-
pfree(ioid);
2379-
return;
2380-
}
2344+
*nindices=length(indexoidlist);
23812345

2382-
if (Irel!= (Relation**)NULL)
2383-
*Irel= (Relation*)palloc(i*sizeof(Relation));
2346+
if (*nindices>0)
2347+
*Irel= (Relation*)palloc(*nindices*sizeof(Relation));
2348+
else
2349+
*Irel=NULL;
23842350

2385-
for (k=0;i>0;)
2351+
i=0;
2352+
foreach(indexoidscan,indexoidlist)
23862353
{
2387-
irel=index_open(ioid[--i]);
2388-
if (irel!= (Relation)NULL)
2389-
{
2390-
if (Irel!= (Relation**)NULL)
2391-
(*Irel)[k]=irel;
2392-
else
2393-
index_close(irel);
2394-
k++;
2395-
}
2396-
else
2397-
elog(NOTICE,"CAN'T OPEN INDEX %u - SKIP IT",ioid[i]);
2398-
}
2399-
*nindices=k;
2400-
pfree(ioid);
2354+
Oidindexoid=lfirsti(indexoidscan);
24012355

2402-
if (Irel!= (Relation**)NULL&&*nindices==0)
2403-
{
2404-
pfree(*Irel);
2405-
*Irel= (Relation*)NULL;
2356+
(*Irel)[i]=index_open(indexoid);
2357+
i++;
24062358
}
24072359

2360+
freeList(indexoidlist);
24082361
}
24092362

24102363

‎src/backend/executor/execMain.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
*
2828
*
2929
* IDENTIFICATION
30-
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.117 2000/06/15 04:09:50 momjian Exp $
30+
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.118 2000/06/17 21:48:47 tgl Exp $
3131
*
3232
*-------------------------------------------------------------------------
3333
*/
@@ -735,7 +735,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
735735
*/
736736
if (resultRelationDesc->rd_rel->relhasindex&&
737737
operation!=CMD_DELETE)
738-
ExecOpenIndices(resultRelationOid,resultRelationInfo);
738+
ExecOpenIndices(resultRelationInfo);
739739

740740
estate->es_result_relation_info=resultRelationInfo;
741741
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp