diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2001-01-05 22:54:37 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2001-01-05 22:54:37 +0000 |
commit | 81d08fcffeed731e6b48bb7474d56c660f0e8294 (patch) | |
tree | 756b2a81e8390ba5025a5bf81ee148efbe34ccd5 /src/backend/utils/cache/inval.c | |
parent | 2fb6cc904555024ef668f5ba096b5bf0ddd3ec26 (diff) | |
download | postgresql-81d08fcffeed731e6b48bb7474d56c660f0e8294.tar.gz postgresql-81d08fcffeed731e6b48bb7474d56c660f0e8294.zip |
Rename and document some invalidation routines to make it clearer that
they don't themselves flush any cache entries, only add to to-do lists
that will be processed later.
Diffstat (limited to 'src/backend/utils/cache/inval.c')
-rw-r--r-- | src/backend/utils/cache/inval.c | 111 |
1 files changed, 74 insertions, 37 deletions
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index 8f4fd626f8b..37f2c8416c4 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -3,14 +3,41 @@ * inval.c * POSTGRES cache invalidation dispatcher code. * + * This is subtle stuff, so pay attention: + * + * When a tuple is updated or deleted, our time qualification rules consider + * that it is *still valid* so long as we are in the same command, ie, + * until the next CommandCounterIncrement() or transaction commit. + * (See utils/time/tqual.c.) At the command boundary, the old tuple stops + * being valid and the new version, if any, becomes valid. Therefore, + * we cannot simply flush a tuple from the system caches during heap_update() + * or heap_delete(). The tuple is still good at that point; what's more, + * even if we did flush it, it might be reloaded into the caches by a later + * request in the same command. So the correct behavior is to keep a list + * of outdated (updated/deleted) tuples and then do the required cache + * flushes at the next command boundary. Similarly, we need a list of + * inserted tuples (including new versions of updated tuples), which we will + * use to flush those tuples out of the caches if we abort the transaction. + * Notice that the first list lives only till command boundary, whereas the + * second lives till end of transaction. Finally, we need a third list of + * all tuples outdated in the current transaction; if we commit, we send + * those invalidation events to all other backends (via the SI message queue) + * so that they can flush obsolete entries from their caches. + * + * We do not need to register EVERY tuple operation in this way, just those + * on tuples in relations that have associated catcaches. Also, whenever + * we see an operation on a pg_class or pg_attribute tuple, we register + * a relcache flush operation for the relation described by that tuple. + * + * * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.38 2000/11/08 22:10:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.39 2001/01/05 22:54:37 tgl Exp $ * - * Note - this code is real crufty... + * Note - this code is real crufty... badly needs a rewrite to improve + * readability and portability. (Shouldn't assume Oid == Index, for example) * *------------------------------------------------------------------------- */ @@ -82,7 +109,8 @@ typedef InvalidationMessageData *InvalidationMessage; * ---------------- * Invalidation info is divided into three parts. * 1) shared invalidation to be registered for all backends - * 2) local invalidation for the transaction itself + * 2) local invalidation for the transaction itself (actually, just + * for the current command within the transaction) * 3) rollback information for the transaction itself (in case we abort) * ---------------- */ @@ -107,7 +135,9 @@ static LocalInvalid RollbackStack = EmptyLocalInvalid; static InvalidationEntry InvalidationEntryAllocate(uint16 size); -static void LocalInvalidInvalidate(LocalInvalid invalid, void (*function) (), bool freemember); +static void LocalInvalidInvalidate(LocalInvalid invalid, + void (*function) (InvalidationMessage), + bool freemember); static LocalInvalid LocalInvalidRegister(LocalInvalid invalid, InvalidationEntry entry); static void DiscardInvalidStack(LocalInvalid *invalid); @@ -161,7 +191,7 @@ LocalInvalidRegister(LocalInvalid invalid, */ static void LocalInvalidInvalidate(LocalInvalid invalid, - void (*function) (), + void (*function) (InvalidationMessage), bool freemember) { InvalidationEntryData *entryDataP; @@ -172,7 +202,7 @@ LocalInvalidInvalidate(LocalInvalid invalid, &((InvalidationUserData *) invalid)->dataP[-1]; if (PointerIsValid(function)) - (*function) ((Pointer) &entryDataP->userData); + (*function) ((InvalidationMessage) &entryDataP->userData); invalid = (Pointer) entryDataP->nextP; @@ -193,7 +223,9 @@ DiscardInvalidStack(LocalInvalid *invalid) locinv = *invalid; *invalid = EmptyLocalInvalid; if (locinv) - LocalInvalidInvalidate(locinv, (void (*) ()) NULL, true); + LocalInvalidInvalidate(locinv, + (void (*) (InvalidationMessage)) NULL, + true); } /* ---------------------------------------------------------------- @@ -269,7 +301,7 @@ CacheIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid, * -------------------------------- */ static void -CacheIdRegisterLocalInvalid(Index cacheId, +CacheIdRegisterLocalInvalid(int cacheId, Index hashIndex, ItemPointer pointer) { @@ -298,7 +330,8 @@ CacheIdRegisterLocalInvalid(Index cacheId, * -------------------------------- */ static void -CacheIdRegisterLocalRollback(Index cacheId, Index hashIndex, +CacheIdRegisterLocalRollback(int cacheId, + Index hashIndex, ItemPointer pointer) { @@ -477,7 +510,7 @@ CacheIdInvalidate(Index cacheId, * -------------------------------- */ static void -ResetSystemCaches() +ResetSystemCaches(void) { ResetSystemCache(); RelationCacheInvalidate(); @@ -585,13 +618,13 @@ InvalidationMessageCacheInvalidate(InvalidationMessage message) } /* -------------------------------- - * RelationInvalidateRelationCache + * PrepareToInvalidateRelationCache * -------------------------------- */ static void -RelationInvalidateRelationCache(Relation relation, - HeapTuple tuple, - void (*function) ()) +PrepareToInvalidateRelationCache(Relation relation, + HeapTuple tuple, + void (*function) (Oid, Oid)) { Oid relationId; Oid objectId; @@ -614,7 +647,7 @@ RelationInvalidateRelationCache(Relation relation, return; /* ---------------- - * can't handle immediate relation descriptor invalidation + * register the relcache-invalidation action in the appropriate list * ---------------- */ Assert(PointerIsValid(function)); @@ -629,11 +662,9 @@ RelationInvalidateRelationCache(Relation relation, * * Note: * This should be called as the first step in processing a transaction. - * This should be called while waiting for a query from the front end - * when other backends are active. */ void -DiscardInvalid() +DiscardInvalid(void) { /* ---------------- * debugging stuff @@ -694,7 +725,8 @@ RegisterInvalid(bool send) * Causes invalidation immediately for the next command of the transaction. * * Note: - * This should be called in time of CommandCounterIncrement(). + * This should be called during CommandCounterIncrement(), + * after we have advanced the command ID. */ void ImmediateLocalInvalidation(bool send) @@ -735,7 +767,7 @@ ImmediateLocalInvalidation(bool send) } /* - * InvokeHeapTupleInvalidation + * PrepareForTupleInvalidation * Invoke functions for the tuple which register invalidation * of catalog/relation cache. * Note: @@ -743,20 +775,21 @@ ImmediateLocalInvalidation(bool send) * Assumes tuple is valid. */ #ifdef INVALIDDEBUG -#define InvokeHeapTupleInvalidation_DEBUG1 \ +#define PrepareForTupleInvalidation_DEBUG1 \ elog(DEBUG, "%s(%s, [%d,%d])", \ funcname,\ RelationGetPhysicalRelationName(relation), \ ItemPointerGetBlockNumber(&tuple->t_self), \ ItemPointerGetOffsetNumber(&tuple->t_self)) #else -#define InvokeHeapTupleInvalidation_DEBUG1 +#define PrepareForTupleInvalidation_DEBUG1 #endif /* defined(INVALIDDEBUG) */ static void -InvokeHeapTupleInvalidation(Relation relation, HeapTuple tuple, - void (*CacheIdRegisterFunc) (), - void (*RelationIdRegisterFunc) (), +PrepareForTupleInvalidation(Relation relation, HeapTuple tuple, + void (*CacheIdRegisterFunc) (int, Index, + ItemPointer), + void (*RelationIdRegisterFunc) (Oid, Oid), const char *funcname) { /* ---------------- @@ -768,8 +801,11 @@ InvokeHeapTupleInvalidation(Relation relation, HeapTuple tuple, if (IsBootstrapProcessingMode()) return; + /* ---------------- - * this only works for system relations now + * We only need to worry about invalidation for tuples that are in + * system relations; user-relation tuples are never in catcaches + * and can't affect the relcache either. * ---------------- */ if (!IsSystemRelationName(NameStr(RelationGetForm(relation)->relname))) @@ -779,23 +815,24 @@ InvokeHeapTupleInvalidation(Relation relation, HeapTuple tuple, * debugging stuff * ---------------- */ - InvokeHeapTupleInvalidation_DEBUG1; + PrepareForTupleInvalidation_DEBUG1; - RelationInvalidateCatalogCacheTuple(relation, tuple, - CacheIdRegisterFunc); + PrepareToInvalidateCacheTuple(relation, tuple, + CacheIdRegisterFunc); - RelationInvalidateRelationCache(relation, tuple, - RelationIdRegisterFunc); + PrepareToInvalidateRelationCache(relation, tuple, + RelationIdRegisterFunc); } /* * RelationInvalidateHeapTuple - * Causes the given tuple in a relation to be invalidated. + * Register the given tuple for invalidation at end of command + * (ie, current command is outdating this tuple). */ void RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple) { - InvokeHeapTupleInvalidation(relation, tuple, + PrepareForTupleInvalidation(relation, tuple, CacheIdRegisterLocalInvalid, RelationIdRegisterLocalInvalid, "RelationInvalidateHeapTuple"); @@ -803,13 +840,13 @@ RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple) /* * RelationMark4RollbackHeapTuple - * keep the given tuple in a relation to be invalidated - * in case of abort. + * Register the given tuple for invalidation in case of abort + * (ie, current command is creating this tuple). */ void RelationMark4RollbackHeapTuple(Relation relation, HeapTuple tuple) { - InvokeHeapTupleInvalidation(relation, tuple, + PrepareForTupleInvalidation(relation, tuple, CacheIdRegisterLocalRollback, RelationIdRegisterLocalRollback, "RelationMark4RollbackHeapTuple"); |