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

Commit74e7b58

Browse files
committed
Fix for failure to clean SysCache entry when a relation is deleted
in the same transaction that created it.
1 parent0bddf3d commit74e7b58

File tree

4 files changed

+61
-57
lines changed

4 files changed

+61
-57
lines changed

‎src/backend/catalog/heap.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.86 1999/05/26 22:57:39 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.87 1999/06/04 02:19:46 tgl Exp $
1111
*
1212
*
1313
* INTERFACE ROUTINES
@@ -812,13 +812,7 @@ heap_create_with_catalog(char *relname,
812812

813813
if (relid!=InvalidOid)
814814
{
815-
816-
/*
817-
* This is heavy-handed, but appears necessary bjm 1999/02/01
818-
* SystemCacheRelationFlushed(relid) is not enough either.
819-
*/
820815
RelationForgetRelation(relid);
821-
ResetSystemCache();
822816
}
823817
}
824818

‎src/backend/catalog/index.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.76 1999/05/26 22:57:39 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.77 1999/06/04 02:19:47 tgl Exp $
1111
*
1212
*
1313
* INTERFACE ROUTINES
@@ -991,13 +991,7 @@ index_create(char *heapRelationName,
991991

992992
if (relid!=InvalidOid)
993993
{
994-
995-
/*
996-
* This is heavy-handed, but appears necessary bjm 1999/02/01
997-
* SystemCacheRelationFlushed(relid) is not enough either.
998-
*/
999994
RelationForgetRelation(relid);
1000-
ResetSystemCache();
1001995
}
1002996
}
1003997

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

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.42 1999/05/31 23:48:04 tgl Exp $
11-
*
12-
* Notes:
13-
*XXX This needs to use exception.h to handle recovery when
14-
*an abort occurs during DisableCache.
10+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.43 1999/06/04 02:19:45 tgl Exp $
1511
*
1612
*-------------------------------------------------------------------------
1713
*/
@@ -66,10 +62,11 @@ static long comphash(long l, char *v);
6662
#defineCACHE6_elog(a,b,c,d,e,f,g)
6763
#endif
6864

69-
CatCache*Caches=NULL;
70-
GlobalMemoryCacheCxt;
65+
staticCatCache*Caches=NULL;/* head of list of caches */
66+
67+
GlobalMemoryCacheCxt;/* context in which caches are allocated */
68+
/* CacheCxt is global because relcache uses it too. */
7169

72-
staticintDisableCache;
7370

7471
/* ----------------
7572
*EQPROC is used in CatalogCacheInitializeCache
@@ -559,16 +556,7 @@ ResetSystemCache()
559556
MemoryContextoldcxt;
560557
structcatcache*cache;
561558

562-
/* ----------------
563-
*sanity checks
564-
* ----------------
565-
*/
566559
CACHE1_elog(DEBUG,"ResetSystemCache called");
567-
if (DisableCache)
568-
{
569-
elog(ERROR,"ResetSystemCache: Called while cache disabled");
570-
return;
571-
}
572560

573561
/* ----------------
574562
*first switch to the cache context so our allocations
@@ -602,11 +590,13 @@ ResetSystemCache()
602590
{
603591
nextelt=DLGetSucc(elt);
604592
CatCacheRemoveCTup(cache,elt);
605-
if (cache->cc_ntup==-1)
606-
elog(ERROR,"ResetSystemCache: cc_ntup<0 (software error)");
593+
if (cache->cc_ntup<0)
594+
elog(NOTICE,
595+
"ResetSystemCache: cc_ntup<0 (software error)");
607596
}
608597
}
609598
cache->cc_ntup=0;/* in case of WARN error above */
599+
cache->busy= false;/* to recover from recursive-use error */
610600
}
611601

612602
CACHE1_elog(DEBUG,"end of ResetSystemCache call");
@@ -621,17 +611,37 @@ ResetSystemCache()
621611
/* --------------------------------
622612
*SystemCacheRelationFlushed
623613
*
624-
*RelationFlushRelation() frees some information referenced in the
625-
*cache structures. So we get informed when this is done and arrange
626-
*for the next SearchSysCache() call that this information is setup
627-
*again.
614+
*This is called by RelationFlushRelation() to clear out cached information
615+
*about a relation being dropped. (This could be a DROP TABLE command,
616+
*or a temp table being dropped at end of transaction, or a table created
617+
*during the current transaction that is being dropped because of abort.)
618+
*Remove all cache entries relevant to the specified relation OID.
619+
*
620+
*A special case occurs when relId is itself one of the cacheable system
621+
*tables --- although those'll never be dropped, they can get flushed from
622+
*the relcache (VACUUM causes this, for example). In that case we need to
623+
*force the next SearchSysCache() call to reinitialize the cache itself,
624+
*because we have info (such as cc_tupdesc) that is pointing at the about-
625+
*to-be-deleted relcache entry.
628626
* --------------------------------
629627
*/
630628
void
631629
SystemCacheRelationFlushed(OidrelId)
632630
{
633631
structcatcache*cache;
634632

633+
/*
634+
* XXX Ideally we'd search the caches and just zap entries that actually
635+
* refer to the indicated relation. For now, we take the brute-force
636+
* approach: just flush the caches entirely.
637+
*/
638+
ResetSystemCache();
639+
640+
/*
641+
* If relcache is dropping a system relation's cache entry, mark the
642+
* associated cache structures invalid, so we can rebuild them from
643+
* scratch (not just repopulate them) next time they are used.
644+
*/
635645
for (cache=Caches;PointerIsValid(cache);cache=cache->cc_next)
636646
{
637647
if (cache->relationId==relId)
@@ -746,6 +756,7 @@ InitSysCache(char *relname,
746756
cp->cc_indname=indname;
747757
cp->cc_tupdesc= (TupleDesc)NULL;
748758
cp->id=id;
759+
cp->busy= false;
749760
cp->cc_maxtup=MAXTUP;
750761
cp->cc_size=NCCBUCK;
751762
cp->cc_nkeys=nkeys;
@@ -902,19 +913,23 @@ SearchSysCache(struct catcache * cache,
902913
/* ----------------
903914
*Tuple was not found in cache, so we have to try and
904915
*retrieve it directly from the relation. If it's found,
905-
*we add it to the cache. We must avoid recursion here,
906-
*so we disable cache operations. If operations are
907-
*currently disabled and we couldn't find the requested item
908-
*in the cache, then this may be a recursive request, and we
909-
*abort with an error.
916+
*we add it to the cache.
917+
*
918+
*To guard against possible infinite recursion, we mark this cache
919+
*"busy" while trying to load a new entry for it. It is OK to
920+
*recursively invoke SearchSysCache for a different cache, but
921+
*a recursive call for the same cache will error out. (We could
922+
*store the specific key(s) being looked for, and consider only
923+
*a recursive request for the same key to be an error, but this
924+
*simple scheme is sufficient for now.)
910925
* ----------------
911926
*/
912927

913-
if (DisableCache)
928+
if (cache->busy)
914929
{
915-
elog(ERROR,"SearchSysCache: Called while cache disabled");
916-
return (HeapTuple)NULL;
930+
elog(ERROR,"SearchSysCache: recursive use of cache %d",cache->id);
917931
}
932+
cache->busy= true;
918933

919934
/* ----------------
920935
*open the relation associated with the cache
@@ -925,10 +940,9 @@ SearchSysCache(struct catcache * cache,
925940
RelationGetRelationName(relation));
926941

927942
/* ----------------
928-
*DisableCache and then switch to the cache memory context.
943+
*Switch to the cache memory context.
929944
* ----------------
930945
*/
931-
DisableCache=1;
932946

933947
if (!CacheCxt)
934948
CacheCxt=CreateGlobalMemory("Cache");
@@ -1011,7 +1025,7 @@ SearchSysCache(struct catcache * cache,
10111025
MemoryContextSwitchTo((MemoryContext)CacheCxt);
10121026
}
10131027

1014-
DisableCache=0;
1028+
cache->busy=false;
10151029

10161030
/* ----------------
10171031
*scan is complete. if tup is valid, we copy it and add the copy to
@@ -1046,7 +1060,8 @@ SearchSysCache(struct catcache * cache,
10461060
DLAddHead(cache->cc_cache[hash],elt);
10471061

10481062
/* ----------------
1049-
*deal with hash bucket overflow
1063+
*If we've exceeded the desired size of this cache,
1064+
*throw away the least recently used entry.
10501065
* ----------------
10511066
*/
10521067
if (++cache->cc_ntup>cache->cc_maxtup)
@@ -1056,13 +1071,12 @@ SearchSysCache(struct catcache * cache,
10561071
elt=DLGetTail(cache->cc_lrulist);
10571072
ct= (CatCTup*)DLE_VAL(elt);
10581073

1059-
if (ct!=nct)
1074+
if (ct!=nct)/* shouldn't be possible, but be safe... */
10601075
{
10611076
CACHE2_elog(DEBUG,"SearchSysCache(%s): Overflow, LRU removal",
10621077
RelationGetRelationName(relation));
10631078

10641079
CatCacheRemoveCTup(cache,elt);
1065-
10661080
}
10671081
}
10681082

‎src/include/utils/catcache.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: catcache.h,v 1.14 1999/02/13 23:22:16 momjian Exp $
9+
* $Id: catcache.h,v 1.15 1999/06/04 02:19:44 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -28,9 +28,11 @@
2828
typedefstructcatctup
2929
{
3030
HeapTuplect_tup;/* A pointer to a tuple*/
31-
Dlelem*ct_node;/* points to LRU list is the CatCTup is in
32-
* the cache, else, points to the cache if
33-
* the CatCTup is in LRU list */
31+
/* Each tuple in the cache has two catctup items, one in the LRU list
32+
* and one in the hashbucket list for its hash value. ct_node in each
33+
* one points to the other one.
34+
*/
35+
Dlelem*ct_node;/* the other catctup for this tuple */
3436
}CatCTup;
3537

3638
/* voodoo constants */
@@ -46,6 +48,7 @@ typedef struct catcache
4648
HeapTuple(*cc_iscanfunc) ();/* index scanfunction */
4749
TupleDesccc_tupdesc;/* tuple descriptor from reldesc */
4850
intid;/* XXX could be improved -hirohama */
51+
boolbusy;/* for detecting recursive lookups */
4952
shortcc_ntup;/* # of tuples in this cache*/
5053
shortcc_maxtup;/* max # of tuples allowed (LRU) */
5154
shortcc_nkeys;
@@ -55,12 +58,11 @@ typedef struct catcache
5558
ScanKeyDatacc_skey[4];
5659
structcatcache*cc_next;
5760
Dllist*cc_lrulist;/* LRU list, most recent first */
58-
Dllist*cc_cache[NCCBUCK+1];
61+
Dllist*cc_cache[NCCBUCK+1];/* hash buckets */
5962
}CatCache;
6063

6164
#defineInvalidCatalogCacheId(-1)
6265

63-
externstructcatcache*Caches;
6466
externGlobalMemoryCacheCxt;
6567

6668
externvoidCatalogCacheIdInvalidate(intcacheId,IndexhashIndex,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp