diff options
Diffstat (limited to 'src/backend/utils/cache/catcache.c')
-rw-r--r-- | src/backend/utils/cache/catcache.c | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 8b606a8da27..aac1e87d87e 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.148 2010/01/02 16:57:55 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.149 2010/02/07 20:48:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -28,6 +28,7 @@ #endif #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/inval.h" #include "utils/memutils.h" #include "utils/rel.h" #include "utils/resowner.h" @@ -679,17 +680,6 @@ ResetCatalogCaches(void) * or a temp table being dropped at end of transaction, or a table created * during the current transaction that is being dropped because of abort.) * Remove all cache entries relevant to the specified relation OID. - * - * A special case occurs when relId is itself one of the cacheable system - * tables --- although those'll never be dropped, they can get flushed from - * the relcache (VACUUM causes this, for example). In that case we need - * to flush all cache entries that came from that table. (At one point we - * also tried to force re-execution of CatalogCacheInitializeCache for - * the cache(s) on that table. This is a bad idea since it leads to all - * kinds of trouble if a cache flush occurs while loading cache entries. - * We now avoid the need to do it by copying cc_tupdesc out of the relcache, - * rather than relying on the relcache to keep a tupdesc for us. Of course - * this assumes the tupdesc of a cachable system table will not change...) */ void CatalogCacheFlushRelation(Oid relId) @@ -706,14 +696,6 @@ CatalogCacheFlushRelation(Oid relId) if (cache->cc_tupdesc == NULL) continue; - /* Does this cache store tuples of the target relation itself? */ - if (cache->cc_tupdesc->attrs[0]->attrelid == relId) - { - /* Yes, so flush all its contents */ - ResetCatalogCache(cache); - continue; - } - /* Does this cache store tuples associated with relations at all? */ if (cache->cc_reloidattr == 0) continue; /* nope, leave it alone */ @@ -776,6 +758,46 @@ CatalogCacheFlushRelation(Oid relId) } /* + * CatalogCacheFlushCatalog + * + * Flush all catcache entries that came from the specified system catalog. + * This is needed after VACUUM FULL/CLUSTER on the catalog, since the + * tuples very likely now have different TIDs than before. (At one point + * we also tried to force re-execution of CatalogCacheInitializeCache for + * the cache(s) on that catalog. This is a bad idea since it leads to all + * kinds of trouble if a cache flush occurs while loading cache entries. + * We now avoid the need to do it by copying cc_tupdesc out of the relcache, + * rather than relying on the relcache to keep a tupdesc for us. Of course + * this assumes the tupdesc of a cachable system table will not change...) + */ +void +CatalogCacheFlushCatalog(Oid catId) +{ + CatCache *cache; + + CACHE2_elog(DEBUG2, "CatalogCacheFlushCatalog called for %u", catId); + + for (cache = CacheHdr->ch_caches; cache; cache = cache->cc_next) + { + /* We can ignore uninitialized caches, since they must be empty */ + if (cache->cc_tupdesc == NULL) + continue; + + /* Does this cache store tuples of the target catalog? */ + if (cache->cc_tupdesc->attrs[0]->attrelid == catId) + { + /* Yes, so flush all its contents */ + ResetCatalogCache(cache); + + /* Tell inval.c to call syscache callbacks for this cache */ + CallSyscacheCallbacks(cache->id, NULL); + } + } + + CACHE1_elog(DEBUG2, "end of CatalogCacheFlushCatalog call"); +} + +/* * InitCatCache * * This allocates and initializes a cache for a system catalog relation. |