Commit 26ac2171 authored by Tom Lane's avatar Tom Lane

Catcaches can now store negative entries as well as positive ones, to

speed up repetitive failed searches; per pghackers discussion in late
January.  inval.c logic substantially simplified, since we can now treat
inserts and deletes alike as far as inval events are concerned.  Some
repair work needed in heap_create_with_catalog, which turns out to have
been doing CommandCounterIncrement at a point where the new relation has
non-self-consistent catalog entries.  With the new inval code, that
resulted in assert failures during a relcache entry rebuild.
parent 592caa08
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.130 2002/03/02 21:39:17 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.131 2002/03/03 17:47:53 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -1131,12 +1131,12 @@ heap_insert(Relation relation, HeapTuple tup) ...@@ -1131,12 +1131,12 @@ heap_insert(Relation relation, HeapTuple tup)
WriteBuffer(buffer); WriteBuffer(buffer);
/* /*
* If tuple is cachable, mark it for rollback from the caches in case * If tuple is cachable, mark it for invalidation from the caches in case
* we abort. Note it is OK to do this after WriteBuffer releases the * we abort. Note it is OK to do this after WriteBuffer releases the
* buffer, because the "tup" data structure is all in local memory, * buffer, because the "tup" data structure is all in local memory,
* not in the shared buffer. * not in the shared buffer.
*/ */
RelationMark4RollbackHeapTuple(relation, tup); CacheInvalidateHeapTuple(relation, tup);
return tup->t_data->t_oid; return tup->t_data->t_oid;
} }
...@@ -1278,7 +1278,7 @@ l1: ...@@ -1278,7 +1278,7 @@ l1:
* look at the contents of the tuple, so we need to hold our refcount * look at the contents of the tuple, so we need to hold our refcount
* on the buffer. * on the buffer.
*/ */
RelationInvalidateHeapTuple(relation, &tp); CacheInvalidateHeapTuple(relation, &tp);
WriteBuffer(buffer); WriteBuffer(buffer);
...@@ -1585,19 +1585,19 @@ l2: ...@@ -1585,19 +1585,19 @@ l2:
* boundary. We have to do this before WriteBuffer because we need to * boundary. We have to do this before WriteBuffer because we need to
* look at the contents of the tuple, so we need to hold our refcount. * look at the contents of the tuple, so we need to hold our refcount.
*/ */
RelationInvalidateHeapTuple(relation, &oldtup); CacheInvalidateHeapTuple(relation, &oldtup);
if (newbuf != buffer) if (newbuf != buffer)
WriteBuffer(newbuf); WriteBuffer(newbuf);
WriteBuffer(buffer); WriteBuffer(buffer);
/* /*
* If new tuple is cachable, mark it for rollback from the caches in * If new tuple is cachable, mark it for invalidation from the caches in
* case we abort. Note it is OK to do this after WriteBuffer releases * case we abort. Note it is OK to do this after WriteBuffer releases
* the buffer, because the "newtup" data structure is all in local * the buffer, because the "newtup" data structure is all in local
* memory, not in the shared buffer. * memory, not in the shared buffer.
*/ */
RelationMark4RollbackHeapTuple(relation, newtup); CacheInvalidateHeapTuple(relation, newtup);
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
} }
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.172 2002/02/19 20:11:11 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.173 2002/03/03 17:47:54 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -800,19 +800,6 @@ index_drop(Oid indexId) ...@@ -800,19 +800,6 @@ index_drop(Oid indexId)
simple_heap_delete(relationRelation, &tuple->t_self); simple_heap_delete(relationRelation, &tuple->t_self);
heap_freetuple(tuple); heap_freetuple(tuple);
/*
* Update the pg_class tuple for the owning relation. We are
* presently too lazy to attempt to compute the new correct value of
* relhasindex (the next VACUUM will fix it if necessary). But we
* must send out a shared-cache-inval notice on the owning relation to
* ensure other backends update their relcache lists of indexes. So,
* unconditionally do setRelhasindex(true).
*
* Possible future improvement: skip the physical tuple update and just
* send out an invalidation message.
*/
setRelhasindex(heapId, true, false, InvalidOid);
heap_close(relationRelation, RowExclusiveLock); heap_close(relationRelation, RowExclusiveLock);
/* /*
...@@ -858,6 +845,15 @@ index_drop(Oid indexId) ...@@ -858,6 +845,15 @@ index_drop(Oid indexId)
smgrunlink(DEFAULT_SMGR, userIndexRelation); smgrunlink(DEFAULT_SMGR, userIndexRelation);
/*
* We are presently too lazy to attempt to compute the new correct value
* of relhasindex (the next VACUUM will fix it if necessary). So there is
* no need to update the pg_class tuple for the owning relation.
* But we must send out a shared-cache-inval notice on the owning relation
* to ensure other backends update their relcache lists of indexes.
*/
CacheInvalidateRelcache(heapId);
/* /*
* Close rels, but keep locks * Close rels, but keep locks
*/ */
...@@ -1076,7 +1072,7 @@ LockClassinfoForUpdate(Oid relid, HeapTuple rtup, ...@@ -1076,7 +1072,7 @@ LockClassinfoForUpdate(Oid relid, HeapTuple rtup,
} }
break; break;
} }
RelationInvalidateHeapTuple(relationRelation, rtup); CacheInvalidateHeapTuple(relationRelation, rtup);
if (confirmCommitted) if (confirmCommitted)
{ {
HeapTupleHeader th = rtup->t_data; HeapTupleHeader th = rtup->t_data;
...@@ -1137,10 +1133,8 @@ IndexesAreActive(Oid relid, bool confirmCommitted) ...@@ -1137,10 +1133,8 @@ IndexesAreActive(Oid relid, bool confirmCommitted)
* *
* NOTE: an important side-effect of this operation is that an SI invalidation * NOTE: an important side-effect of this operation is that an SI invalidation
* message is sent out to all backends --- including me --- causing relcache * message is sent out to all backends --- including me --- causing relcache
* entries to be flushed or updated with the new hasindex data. * entries to be flushed or updated with the new hasindex data. This must
* Therefore, we execute the update even if relhasindex has the right value * happen even if we find that no change is needed in the pg_class row.
* already. Possible future improvement: skip the disk update and just send
* an SI message in that case.
* ---------------- * ----------------
*/ */
void void
...@@ -1149,6 +1143,7 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid) ...@@ -1149,6 +1143,7 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
Relation pg_class; Relation pg_class;
HeapTuple tuple; HeapTuple tuple;
Form_pg_class classtuple; Form_pg_class classtuple;
bool dirty = false;
HeapScanDesc pg_class_scan = NULL; HeapScanDesc pg_class_scan = NULL;
/* /*
...@@ -1192,13 +1187,28 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid) ...@@ -1192,13 +1187,28 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE); LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE);
classtuple = (Form_pg_class) GETSTRUCT(tuple); classtuple = (Form_pg_class) GETSTRUCT(tuple);
if (classtuple->relhasindex != hasindex)
{
classtuple->relhasindex = hasindex; classtuple->relhasindex = hasindex;
dirty = true;
}
if (isprimary) if (isprimary)
{
if (!classtuple->relhaspkey)
{
classtuple->relhaspkey = true; classtuple->relhaspkey = true;
dirty = true;
}
}
if (OidIsValid(reltoastidxid)) if (OidIsValid(reltoastidxid))
{ {
Assert(classtuple->relkind == RELKIND_TOASTVALUE); Assert(classtuple->relkind == RELKIND_TOASTVALUE);
if (classtuple->reltoastidxid != reltoastidxid)
{
classtuple->reltoastidxid = reltoastidxid; classtuple->reltoastidxid = reltoastidxid;
dirty = true;
}
} }
if (pg_class_scan) if (pg_class_scan)
...@@ -1210,10 +1220,10 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid) ...@@ -1210,10 +1220,10 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
WriteNoReleaseBuffer(pg_class_scan->rs_cbuf); WriteNoReleaseBuffer(pg_class_scan->rs_cbuf);
/* Send out shared cache inval if necessary */ /* Send out shared cache inval if necessary */
if (!IsBootstrapProcessingMode()) if (!IsBootstrapProcessingMode())
RelationInvalidateHeapTuple(pg_class, tuple); CacheInvalidateHeapTuple(pg_class, tuple);
BufferSync(); BufferSync();
} }
else else if (dirty)
{ {
simple_heap_update(pg_class, &tuple->t_self, tuple); simple_heap_update(pg_class, &tuple->t_self, tuple);
...@@ -1228,6 +1238,11 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid) ...@@ -1228,6 +1238,11 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
CatalogCloseIndices(Num_pg_class_indices, idescs); CatalogCloseIndices(Num_pg_class_indices, idescs);
} }
} }
else
{
/* no need to change tuple, but force relcache rebuild anyway */
CacheInvalidateRelcache(relid);
}
if (!pg_class_scan) if (!pg_class_scan)
heap_freetuple(tuple); heap_freetuple(tuple);
...@@ -1280,7 +1295,7 @@ setNewRelfilenode(Relation relation) ...@@ -1280,7 +1295,7 @@ setNewRelfilenode(Relation relation)
classTuple = &lockTupleData; classTuple = &lockTupleData;
/* Send out shared cache inval if necessary */ /* Send out shared cache inval if necessary */
if (!IsBootstrapProcessingMode()) if (!IsBootstrapProcessingMode())
RelationInvalidateHeapTuple(pg_class, classTuple); CacheInvalidateHeapTuple(pg_class, classTuple);
/* Update the buffer in-place */ /* Update the buffer in-place */
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
((Form_pg_class) GETSTRUCT(classTuple))->relfilenode = newrelfilenode; ((Form_pg_class) GETSTRUCT(classTuple))->relfilenode = newrelfilenode;
...@@ -1442,7 +1457,7 @@ UpdateStats(Oid relid, double reltuples) ...@@ -1442,7 +1457,7 @@ UpdateStats(Oid relid, double reltuples)
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK); LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
WriteNoReleaseBuffer(pg_class_scan->rs_cbuf); WriteNoReleaseBuffer(pg_class_scan->rs_cbuf);
if (!IsBootstrapProcessingMode()) if (!IsBootstrapProcessingMode())
RelationInvalidateHeapTuple(pg_class, tuple); CacheInvalidateHeapTuple(pg_class, tuple);
} }
else else
{ {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.215 2002/03/02 21:39:23 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.216 2002/03/03 17:47:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -527,7 +527,7 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples, ...@@ -527,7 +527,7 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
* no flush will occur, but no great harm is done since there are no * no flush will occur, but no great harm is done since there are no
* noncritical state updates here.) * noncritical state updates here.)
*/ */
RelationInvalidateHeapTuple(rd, &rtup); CacheInvalidateHeapTuple(rd, &rtup);
/* Write the buffer */ /* Write the buffer */
WriteBuffer(buffer); WriteBuffer(buffer);
...@@ -583,7 +583,7 @@ vac_update_dbstats(Oid dbid, ...@@ -583,7 +583,7 @@ vac_update_dbstats(Oid dbid,
dbform->datfrozenxid = frozenXID; dbform->datfrozenxid = frozenXID;
/* invalidate the tuple in the cache and write the buffer */ /* invalidate the tuple in the cache and write the buffer */
RelationInvalidateHeapTuple(relation, tuple); CacheInvalidateHeapTuple(relation, tuple);
WriteNoReleaseBuffer(scan->rs_cbuf); WriteNoReleaseBuffer(scan->rs_cbuf);
heap_endscan(scan); heap_endscan(scan);
...@@ -1796,7 +1796,10 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, ...@@ -1796,7 +1796,10 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
*/ */
heap_copytuple_with_tuple(&tuple, &newtup); heap_copytuple_with_tuple(&tuple, &newtup);
RelationInvalidateHeapTuple(onerel, &tuple); /*
* register invalidation of source tuple in catcaches.
*/
CacheInvalidateHeapTuple(onerel, &tuple);
/* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */ /* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */
START_CRIT_SECTION(); START_CRIT_SECTION();
...@@ -1953,7 +1956,15 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, ...@@ -1953,7 +1956,15 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
/* copy tuple */ /* copy tuple */
heap_copytuple_with_tuple(&tuple, &newtup); heap_copytuple_with_tuple(&tuple, &newtup);
RelationInvalidateHeapTuple(onerel, &tuple); /*
* register invalidation of source tuple in catcaches.
*
* (Note: we do not need to register the copied tuple,
* because we are not changing the tuple contents and
* so there cannot be any need to flush negative
* catcache entries.)
*/
CacheInvalidateHeapTuple(onerel, &tuple);
/* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */ /* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */
START_CRIT_SECTION(); START_CRIT_SECTION();
......
This diff is collapsed.
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.152 2002/02/19 20:11:17 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.153 2002/03/03 17:47:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2065,10 +2065,16 @@ RelationBuildLocalRelation(const char *relname, ...@@ -2065,10 +2065,16 @@ RelationBuildLocalRelation(const char *relname,
rel->rd_isnailed = true; rel->rd_isnailed = true;
/* /*
* create a new tuple descriptor from the one passed in (we do this to * create a new tuple descriptor from the one passed in. We do this
* copy it into the cache context) * partly to copy it into the cache context, and partly because the
* new relation can't have any defaults or constraints yet; they
* have to be added in later steps, because they require additions
* to multiple system catalogs. We can copy attnotnull constraints
* here, however.
*/ */
rel->rd_att = CreateTupleDescCopyConstr(tupDesc); rel->rd_att = CreateTupleDescCopy(tupDesc);
for (i = 0; i < natts; i++)
rel->rd_att->attrs[i]->attnotnull = tupDesc->attrs[i]->attnotnull;
/* /*
* initialize relation tuple form (caller may add/override data later) * initialize relation tuple form (caller may add/override data later)
...@@ -2082,8 +2088,6 @@ RelationBuildLocalRelation(const char *relname, ...@@ -2082,8 +2088,6 @@ RelationBuildLocalRelation(const char *relname,
rel->rd_rel->relhasoids = true; rel->rd_rel->relhasoids = true;
rel->rd_rel->relnatts = natts; rel->rd_rel->relnatts = natts;
rel->rd_rel->reltype = InvalidOid; rel->rd_rel->reltype = InvalidOid;
if (tupDesc->constr)
rel->rd_rel->relchecks = tupDesc->constr->num_check;
/* /*
* Insert relation OID and database/tablespace ID into the right * Insert relation OID and database/tablespace ID into the right
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: sinval.h,v 1.25 2001/11/05 17:46:35 momjian Exp $ * $Id: sinval.h,v 1.26 2002/03/03 17:47:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -28,22 +28,32 @@ ...@@ -28,22 +28,32 @@
* are available to identify other inval message types. * are available to identify other inval message types.
* *
* Shared-inval events are initially driven by detecting tuple inserts, * Shared-inval events are initially driven by detecting tuple inserts,
* updates and deletions in system catalogs (see RelationInvalidateHeapTuple * updates and deletions in system catalogs (see CacheInvalidateHeapTuple).
* and RelationMark4RollbackHeapTuple). Note that some system catalogs have * An update generates two inval events, one for the old tuple and one for
* multiple caches on them (with different indexes). On detecting a tuple * the new --- this is needed to get rid of both positive entries for the
* invalidation in such a catalog, a separate catcache inval message must be * old tuple, and negative cache entries associated with the new tuple's
* generated for each of its caches. The catcache inval message carries the * cache key. (This could perhaps be optimized down to one event when the
* hash index for the target tuple, so that the catcache only needs to search * cache key is not changing, but for now we don't bother to try.) Note that
* one hash chain not all its chains. Of course this assumes that all the * the inval events themselves don't actually say whether the tuple is being
* backends are using identical hashing code, but that should be OK. * inserted or deleted.
*
* Note that some system catalogs have multiple caches on them (with different
* indexes). On detecting a tuple invalidation in such a catalog, separate
* catcache inval messages must be generated for each of its caches. The
* catcache inval messages carry the hash value for the target tuple, so
* that the catcache only needs to search one hash chain not all its chains,
* and so that negative cache entries can be recognized with good accuracy.
* (Of course this assumes that all the backends are using identical hashing
* code, but that should be OK.)
*/ */
typedef struct typedef struct
{ {
/* note: field layout chosen with an eye to alignment concerns */
int16 id; /* cache ID --- must be first */ int16 id; /* cache ID --- must be first */
uint16 hashIndex; /* hashchain index within this catcache */
Oid dbId; /* database ID, or 0 if a shared relation */
ItemPointerData tuplePtr; /* tuple identifier in cached relation */ ItemPointerData tuplePtr; /* tuple identifier in cached relation */
Oid dbId; /* database ID, or 0 if a shared relation */
uint32 hashValue; /* hash value of key for this catcache */
} SharedInvalCatcacheMsg; } SharedInvalCatcacheMsg;
#define SHAREDINVALRELCACHE_ID (-1) #define SHAREDINVALRELCACHE_ID (-1)
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catcache.h,v 1.38 2002/02/19 20:11:19 tgl Exp $ * $Id: catcache.h,v 1.39 2002/03/03 17:47:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -35,20 +35,28 @@ typedef struct catcache ...@@ -35,20 +35,28 @@ typedef struct catcache
struct catcache *cc_next; /* link to next catcache */ struct catcache *cc_next; /* link to next catcache */
char *cc_relname; /* name of relation the tuples come from */ char *cc_relname; /* name of relation the tuples come from */
char *cc_indname; /* name of index matching cache keys */ char *cc_indname; /* name of index matching cache keys */
int cc_reloidattr; /* AttrNumber of relation OID, or 0 */ Oid cc_reloid; /* OID of relation the tuples come from */
bool cc_relisshared; /* is relation shared? */ bool cc_relisshared; /* is relation shared? */
TupleDesc cc_tupdesc; /* tuple descriptor (copied from reldesc) */ TupleDesc cc_tupdesc; /* tuple descriptor (copied from reldesc) */
int cc_reloidattr; /* AttrNumber of relation OID attr, or 0 */
int cc_ntup; /* # of tuples currently in this cache */ int cc_ntup; /* # of tuples currently in this cache */
int cc_size; /* # of hash buckets in this cache */ int cc_size; /* # of hash buckets in this cache */
int cc_nkeys; /* number of keys (1..4) */ int cc_nkeys; /* number of keys (1..4) */
int cc_key[4]; /* AttrNumber of each key */ int cc_key[4]; /* AttrNumber of each key */
PGFunction cc_hashfunc[4]; /* hash function to use for each key */ PGFunction cc_hashfunc[4]; /* hash function to use for each key */
ScanKeyData cc_skey[4]; /* precomputed key info for heap scans */ ScanKeyData cc_skey[4]; /* precomputed key info for heap scans */
bool cc_isname[4]; /* flag key columns that are NAMEs */
#ifdef CATCACHE_STATS #ifdef CATCACHE_STATS
long cc_searches; /* total # searches against this cache */ long cc_searches; /* total # searches against this cache */
long cc_hits; /* # of matches against existing entry */ long cc_hits; /* # of matches against existing entry */
long cc_neg_hits; /* # of matches against negative entry */
long cc_newloads; /* # of successful loads of new entry */ long cc_newloads; /* # of successful loads of new entry */
/* cc_searches - (cc_hits + cc_newloads) is # of failed searches */ /*
* cc_searches - (cc_hits + cc_neg_hits + cc_newloads) is number of
* failed searches, each of which will result in loading a negative entry
*/
long cc_invals; /* # of entries invalidated from cache */
long cc_discards; /* # of entries discarded due to overflow */
#endif #endif
Dllist cc_bucket[1]; /* hash buckets --- VARIABLE LENGTH ARRAY */ Dllist cc_bucket[1]; /* hash buckets --- VARIABLE LENGTH ARRAY */
} CatCache; /* VARIABLE LENGTH STRUCT */ } CatCache; /* VARIABLE LENGTH STRUCT */
...@@ -68,11 +76,18 @@ typedef struct catctup ...@@ -68,11 +76,18 @@ typedef struct catctup
* A tuple marked "dead" must not be returned by subsequent searches. * A tuple marked "dead" must not be returned by subsequent searches.
* However, it won't be physically deleted from the cache until its * However, it won't be physically deleted from the cache until its
* refcount goes to zero. * refcount goes to zero.
*
* A negative cache entry is an assertion that there is no tuple
* matching a particular key. This is just as useful as a normal entry
* so far as avoiding catalog searches is concerned. Management of
* positive and negative entries is identical.
*/ */
Dlelem lrulist_elem; /* list member of global LRU list */ Dlelem lrulist_elem; /* list member of global LRU list */
Dlelem cache_elem; /* list member of per-bucket list */ Dlelem cache_elem; /* list member of per-bucket list */
int refcount; /* number of active references */ int refcount; /* number of active references */
bool dead; /* dead but not yet removed? */ bool dead; /* dead but not yet removed? */
bool negative; /* negative cache entry? */
uint32 hash_value; /* hash value for this tuple's keys */
HeapTupleData tuple; /* tuple management header */ HeapTupleData tuple; /* tuple management header */
} CatCTup; } CatCTup;
...@@ -104,10 +119,10 @@ extern void ReleaseCatCache(HeapTuple tuple); ...@@ -104,10 +119,10 @@ extern void ReleaseCatCache(HeapTuple tuple);
extern void ResetCatalogCaches(void); extern void ResetCatalogCaches(void);
extern void CatalogCacheFlushRelation(Oid relId); extern void CatalogCacheFlushRelation(Oid relId);
extern void CatalogCacheIdInvalidate(int cacheId, Index hashIndex, extern void CatalogCacheIdInvalidate(int cacheId, uint32 hashValue,
ItemPointer pointer); ItemPointer pointer);
extern void PrepareToInvalidateCacheTuple(Relation relation, extern void PrepareToInvalidateCacheTuple(Relation relation,
HeapTuple tuple, HeapTuple tuple,
void (*function) (int, Index, ItemPointer, Oid)); void (*function) (int, uint32, ItemPointer, Oid));
#endif /* CATCACHE_H */ #endif /* CATCACHE_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: inval.h,v 1.23 2001/11/05 17:46:36 momjian Exp $ * $Id: inval.h,v 1.24 2002/03/03 17:47:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -23,8 +23,8 @@ extern void AtEOXactInvalidationMessages(bool isCommit); ...@@ -23,8 +23,8 @@ extern void AtEOXactInvalidationMessages(bool isCommit);
extern void CommandEndInvalidationMessages(bool isCommit); extern void CommandEndInvalidationMessages(bool isCommit);
extern void RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple); extern void CacheInvalidateHeapTuple(Relation relation, HeapTuple tuple);
extern void RelationMark4RollbackHeapTuple(Relation relation, HeapTuple tuple); extern void CacheInvalidateRelcache(Oid relationId);
#endif /* INVAL_H */ #endif /* INVAL_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment