summaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/catcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache/catcache.c')
-rw-r--r--src/backend/utils/cache/catcache.c62
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.