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

Commit8ec9438

Browse files
committed
Fix things so that when CREATE INDEX CONCURRENTLY sets pg_index.indisvalid
true at the very end of its processing, the update is broadcast via ashared-cache-inval message for the index; without this, existing backends thatalready have relcache entries for the index might never see it become valid.Also, force a relcache inval on the index's parent table at the same time,so that any cached plans for that table are re-planned; this ensures thatthe newly valid index will be used if appropriate. Aside from makingC.I.C. behave more reasonably, this is necessary infrastructure for someaspects of the HOT patch. Pavan Deolasee, with a little further stuff fromme.
1 parent229d338 commit8ec9438

File tree

3 files changed

+75
-21
lines changed

3 files changed

+75
-21
lines changed

‎src/backend/commands/indexcmds.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.157 2007/03/13 00:33:39 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.158 2007/05/02 21:08:45 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -41,6 +41,7 @@
4141
#include"utils/acl.h"
4242
#include"utils/builtins.h"
4343
#include"utils/fmgroids.h"
44+
#include"utils/inval.h"
4445
#include"utils/lsyscache.h"
4546
#include"utils/memutils.h"
4647
#include"utils/relcache.h"
@@ -514,7 +515,9 @@ DefineIndex(RangeVar *heapRelation,
514515
for (ixcnt=0;ixcnt<snapshot->xcnt;ixcnt++)
515516
XactLockTableWait(snapshot->xip[ixcnt]);
516517

517-
/* Index can now be marked valid -- update its pg_index entry */
518+
/*
519+
* Index can now be marked valid -- update its pg_index entry
520+
*/
518521
pg_index=heap_open(IndexRelationId,RowExclusiveLock);
519522

520523
indexTuple=SearchSysCacheCopy(INDEXRELID,
@@ -534,6 +537,15 @@ DefineIndex(RangeVar *heapRelation,
534537

535538
heap_close(pg_index,RowExclusiveLock);
536539

540+
/*
541+
* The pg_index update will cause backends (including this one) to update
542+
* relcache entries for the index itself, but we should also send a
543+
* relcache inval on the parent table to force replanning of cached plans.
544+
* Otherwise existing sessions might fail to use the new index where it
545+
* would be useful.
546+
*/
547+
CacheInvalidateRelcacheByRelid(heaprelid.relId);
548+
537549
/*
538550
* Last thing to do is release the session-level lock on the parent table.
539551
*/

‎src/backend/utils/cache/inval.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
* Portions Copyright (c) 1994, Regents of the University of California
8181
*
8282
* IDENTIFICATION
83-
* $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.79 2007/01/05 22:19:43 momjian Exp $
83+
* $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.80 2007/05/02 21:08:46 tgl Exp $
8484
*
8585
*-------------------------------------------------------------------------
8686
*/
@@ -590,12 +590,27 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple)
590590
* KLUGE ALERT: we always send the relcache event with MyDatabaseId,
591591
* even if the rel in question is shared (which we can't easily tell).
592592
* This essentially means that only backends in this same database
593-
* will react to the relcache flush request. This is in fact
593+
* will react to the relcache flush request.This is in fact
594594
* appropriate, since only those backends could see our pg_attribute
595-
* change anyway. It looks a bit ugly though.
595+
* change anyway. It looks a bit ugly though. (In practice, shared
596+
* relations can't have schema changes after bootstrap, so we should
597+
* never come here for a shared rel anyway.)
596598
*/
597599
databaseId=MyDatabaseId;
598600
}
601+
elseif (tupleRelId==IndexRelationId)
602+
{
603+
Form_pg_indexindextup= (Form_pg_index)GETSTRUCT(tuple);
604+
605+
/*
606+
* When a pg_index row is updated, we should send out a relcache inval
607+
* for the index relation. As above, we don't know the shared status
608+
* of the index, but in practice it doesn't matter since indexes of
609+
* shared catalogs can't have such updates.
610+
*/
611+
relationId=indextup->indexrelid;
612+
databaseId=MyDatabaseId;
613+
}
599614
else
600615
return;
601616

‎src/backend/utils/cache/relcache.c

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.259 2007/03/29 00:15:38 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.260 2007/05/02 21:08:46 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -181,7 +181,7 @@ static HTAB *OpClassCache = NULL;
181181

182182
staticvoidRelationClearRelation(Relationrelation,boolrebuild);
183183

184-
staticvoidRelationReloadClassinfo(Relationrelation);
184+
staticvoidRelationReloadIndexInfo(Relationrelation);
185185
staticvoidRelationFlushRelation(Relationrelation);
186186
staticboolload_relcache_init_file(void);
187187
staticvoidwrite_relcache_init_file(void);
@@ -1504,7 +1504,7 @@ RelationIdGetRelation(Oid relationId)
15041504
RelationIncrementReferenceCount(rd);
15051505
/* revalidate nailed index if necessary */
15061506
if (!rd->rd_isvalid)
1507-
RelationReloadClassinfo(rd);
1507+
RelationReloadIndexInfo(rd);
15081508
returnrd;
15091509
}
15101510

@@ -1579,24 +1579,24 @@ RelationClose(Relation relation)
15791579
}
15801580

15811581
/*
1582-
*RelationReloadClassinfo - reloadthe pg_class row (only)
1582+
*RelationReloadIndexInfo - reloadminimal information for an open index
15831583
*
1584-
*This function is used only for indexes.We currently allow only the
1585-
*pg_class row of an existing index to change (to support changes of
1586-
*owner, tablespace, or relfilenode), not its pg_index row or other
1587-
*subsidiary index schema information. Therefore it's sufficient to do
1588-
*this whenwegetanSI invalidation. Furthermore, there are cases
1589-
*where it's necessary not to throw awaytheindex information, especially
1590-
*for "nailed" indexes which we are unable to rebuild on-the-fly.
1584+
*This function is used only for indexes.A relcache inval on an index
1585+
*can mean that its pg_class or pg_index row changed. There are only
1586+
*very limited changes that are allowed to an existing index's schema,
1587+
*so we can update the relcache entry without a complete rebuild; which
1588+
*is fortunate becausewecan't rebuildanindex entry that is "nailed"
1589+
*and/or in active use. We support full replacement ofthepg_class row,
1590+
*as well as updates of a few simple fields ofthe pg_index row.
15911591
*
1592-
*We can't necessarily reread thepg_class row right away; we might be
1592+
*We can't necessarily reread thecatalog rows right away; we might be
15931593
*in a failed transaction when we receive the SI notification. If so,
15941594
*RelationClearRelation just marks the entry as invalid by setting
15951595
*rd_isvalid to false. This routine is called to fix the entry when it
15961596
*is next needed.
15971597
*/
15981598
staticvoid
1599-
RelationReloadClassinfo(Relationrelation)
1599+
RelationReloadIndexInfo(Relationrelation)
16001600
{
16011601
boolindexOK;
16021602
HeapTuplepg_class_tuple;
@@ -1635,6 +1635,33 @@ RelationReloadClassinfo(Relation relation)
16351635
if (relation->rd_amcache)
16361636
pfree(relation->rd_amcache);
16371637
relation->rd_amcache=NULL;
1638+
1639+
/*
1640+
* For a non-system index, there are fields of the pg_index row that are
1641+
* allowed to change, so re-read that row and update the relcache entry.
1642+
* Most of the info derived from pg_index (such as support function lookup
1643+
* info) cannot change, and indeed the whole point of this routine is to
1644+
* update the relcache entry without clobbering that data; so wholesale
1645+
* replacement is not appropriate.
1646+
*/
1647+
if (!IsSystemRelation(relation))
1648+
{
1649+
HeapTupletuple;
1650+
Form_pg_indexindex;
1651+
1652+
tuple=SearchSysCache(INDEXRELID,
1653+
ObjectIdGetDatum(RelationGetRelid(relation)),
1654+
0,0,0);
1655+
if (!HeapTupleIsValid(tuple))
1656+
elog(ERROR,"cache lookup failed for index %u",
1657+
RelationGetRelid(relation));
1658+
index= (Form_pg_index)GETSTRUCT(tuple);
1659+
1660+
relation->rd_index->indisvalid=index->indisvalid;
1661+
1662+
ReleaseSysCache(tuple);
1663+
}
1664+
16381665
/* Okay, now it's valid again */
16391666
relation->rd_isvalid= true;
16401667
}
@@ -1683,7 +1710,7 @@ RelationClearRelation(Relation relation, bool rebuild)
16831710
{
16841711
relation->rd_isvalid= false;/* needs to be revalidated */
16851712
if (relation->rd_refcnt>1)
1686-
RelationReloadClassinfo(relation);
1713+
RelationReloadIndexInfo(relation);
16871714
}
16881715
return;
16891716
}
@@ -1693,14 +1720,14 @@ RelationClearRelation(Relation relation, bool rebuild)
16931720
* have valid index support information. This avoids problems with active
16941721
* use of the index support information. As with nailed indexes, we
16951722
* re-read the pg_class row to handle possible physical relocation of the
1696-
* index.
1723+
* index, and we check for pg_index updates too.
16971724
*/
16981725
if (relation->rd_rel->relkind==RELKIND_INDEX&&
16991726
relation->rd_refcnt>0&&
17001727
relation->rd_indexcxt!=NULL)
17011728
{
17021729
relation->rd_isvalid= false;/* needs to be revalidated */
1703-
RelationReloadClassinfo(relation);
1730+
RelationReloadIndexInfo(relation);
17041731
return;
17051732
}
17061733

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp