Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 81d08fc

Browse files
committed
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.
1 parent 2fb6cc9 commit 81d08fc

File tree

3 files changed

+106
-50
lines changed

3 files changed

+106
-50
lines changed

src/backend/utils/cache/catcache.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.73 2000/11/24 04:16:12 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.74 2001/01/05 22:54:37 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1047,17 +1047,36 @@ ReleaseCatCache(HeapTuple tuple)
10471047
}
10481048

10491049
/* --------------------------------
1050-
* RelationInvalidateCatalogCacheTuple()
1050+
* PrepareToInvalidateCacheTuple()
10511051
*
1052-
* Invalidate a tuple from a specific relation. This call determines the
1053-
* cache in question and calls CatalogCacheIdInvalidate(). It is -ok-
1054-
* if the relation cannot be found, it simply means this backend has yet
1055-
* to open it.
1052+
* This is part of a rather subtle chain of events, so pay attention:
1053+
*
1054+
* When a tuple is updated or deleted, it cannot be flushed from the
1055+
* catcaches immediately, for reasons explained at the top of inval.c.
1056+
* Instead we have to add entry(s) for the tuple to a list of pending tuple
1057+
* invalidations that will be done at the end of the command or transaction.
1058+
*
1059+
* The lists of tuples that need to be flushed are kept by inval.c. This
1060+
* routine is a helper routine for inval.c. Given a tuple belonging to
1061+
* the specified relation, find all catcaches it could be in, compute the
1062+
* correct hashindex for each such catcache, and call the specified function
1063+
* to record the cache id, hashindex, and tuple ItemPointer in inval.c's
1064+
* lists. CatalogCacheIdInvalidate will be called later, if appropriate,
1065+
* using the recorded information.
1066+
*
1067+
* Note that it is irrelevant whether the given tuple is actually loaded
1068+
* into the catcache at the moment. Even if it's not there now, it might
1069+
* be by the end of the command, so we have to be prepared to flush it.
1070+
*
1071+
* Also note that it's not an error if there are no catcaches for the
1072+
* specified relation. inval.c doesn't know exactly which rels have
1073+
* catcaches --- it will call this routine for any tuple that's in a
1074+
* system relation.
10561075
* --------------------------------
10571076
*/
10581077
void
1059-
RelationInvalidateCatalogCacheTuple(Relation relation,
1060-
HeapTuple tuple,
1078+
PrepareToInvalidateCacheTuple(Relation relation,
1079+
HeapTuple tuple,
10611080
void (*function) (int, Index, ItemPointer))
10621081
{
10631082
CatCache *ccp;
@@ -1069,13 +1088,13 @@ RelationInvalidateCatalogCacheTuple(Relation relation,
10691088
Assert(RelationIsValid(relation));
10701089
Assert(HeapTupleIsValid(tuple));
10711090
Assert(PointerIsValid(function));
1072-
CACHE1_elog(DEBUG, "RelationInvalidateCatalogCacheTuple: called");
1091+
CACHE1_elog(DEBUG, "PrepareToInvalidateCacheTuple: called");
10731092

10741093
/* ----------------
10751094
* for each cache
10761095
* if the cache contains tuples from the specified relation
1077-
* call the invalidation function on the tuples
1078-
* in the proper hash bucket
1096+
* compute the tuple's hash index in this cache,
1097+
* and call the passed function to register the information.
10791098
* ----------------
10801099
*/
10811100

src/backend/utils/cache/inval.c

Lines changed: 74 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,41 @@
33
* inval.c
44
* POSTGRES cache invalidation dispatcher code.
55
*
6+
* This is subtle stuff, so pay attention:
7+
*
8+
* When a tuple is updated or deleted, our time qualification rules consider
9+
* that it is *still valid* so long as we are in the same command, ie,
10+
* until the next CommandCounterIncrement() or transaction commit.
11+
* (See utils/time/tqual.c.) At the command boundary, the old tuple stops
12+
* being valid and the new version, if any, becomes valid. Therefore,
13+
* we cannot simply flush a tuple from the system caches during heap_update()
14+
* or heap_delete(). The tuple is still good at that point; what's more,
15+
* even if we did flush it, it might be reloaded into the caches by a later
16+
* request in the same command. So the correct behavior is to keep a list
17+
* of outdated (updated/deleted) tuples and then do the required cache
18+
* flushes at the next command boundary. Similarly, we need a list of
19+
* inserted tuples (including new versions of updated tuples), which we will
20+
* use to flush those tuples out of the caches if we abort the transaction.
21+
* Notice that the first list lives only till command boundary, whereas the
22+
* second lives till end of transaction. Finally, we need a third list of
23+
* all tuples outdated in the current transaction; if we commit, we send
24+
* those invalidation events to all other backends (via the SI message queue)
25+
* so that they can flush obsolete entries from their caches.
26+
*
27+
* We do not need to register EVERY tuple operation in this way, just those
28+
* on tuples in relations that have associated catcaches. Also, whenever
29+
* we see an operation on a pg_class or pg_attribute tuple, we register
30+
* a relcache flush operation for the relation described by that tuple.
31+
*
32+
*
633
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
734
* Portions Copyright (c) 1994, Regents of the University of California
835
*
9-
*
1036
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.38 2000/11/08 22:10:01 tgl Exp $
37+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.39 2001/01/05 22:54:37 tgl Exp $
1238
*
13-
* Note - this code is real crufty...
39+
* Note - this code is real crufty... badly needs a rewrite to improve
40+
* readability and portability. (Shouldn't assume Oid == Index, for example)
1441
*
1542
*-------------------------------------------------------------------------
1643
*/
@@ -82,7 +109,8 @@ typedef InvalidationMessageData *InvalidationMessage;
82109
* ----------------
83110
* Invalidation info is divided into three parts.
84111
* 1) shared invalidation to be registered for all backends
85-
* 2) local invalidation for the transaction itself
112+
* 2) local invalidation for the transaction itself (actually, just
113+
* for the current command within the transaction)
86114
* 3) rollback information for the transaction itself (in case we abort)
87115
* ----------------
88116
*/
@@ -107,7 +135,9 @@ static LocalInvalid RollbackStack = EmptyLocalInvalid;
107135

108136

109137
static InvalidationEntry InvalidationEntryAllocate(uint16 size);
110-
static void LocalInvalidInvalidate(LocalInvalid invalid, void (*function) (), bool freemember);
138+
static void LocalInvalidInvalidate(LocalInvalid invalid,
139+
void (*function) (InvalidationMessage),
140+
bool freemember);
111141
static LocalInvalid LocalInvalidRegister(LocalInvalid invalid,
112142
InvalidationEntry entry);
113143
static void DiscardInvalidStack(LocalInvalid *invalid);
@@ -161,7 +191,7 @@ LocalInvalidRegister(LocalInvalid invalid,
161191
*/
162192
static void
163193
LocalInvalidInvalidate(LocalInvalid invalid,
164-
void (*function) (),
194+
void (*function) (InvalidationMessage),
165195
bool freemember)
166196
{
167197
InvalidationEntryData *entryDataP;
@@ -172,7 +202,7 @@ LocalInvalidInvalidate(LocalInvalid invalid,
172202
&((InvalidationUserData *) invalid)->dataP[-1];
173203

174204
if (PointerIsValid(function))
175-
(*function) ((Pointer) &entryDataP->userData);
205+
(*function) ((InvalidationMessage) &entryDataP->userData);
176206

177207
invalid = (Pointer) entryDataP->nextP;
178208

@@ -193,7 +223,9 @@ DiscardInvalidStack(LocalInvalid *invalid)
193223
locinv = *invalid;
194224
*invalid = EmptyLocalInvalid;
195225
if (locinv)
196-
LocalInvalidInvalidate(locinv, (void (*) ()) NULL, true);
226+
LocalInvalidInvalidate(locinv,
227+
(void (*) (InvalidationMessage)) NULL,
228+
true);
197229
}
198230

199231
/* ----------------------------------------------------------------
@@ -269,7 +301,7 @@ CacheIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid,
269301
* --------------------------------
270302
*/
271303
static void
272-
CacheIdRegisterLocalInvalid(Index cacheId,
304+
CacheIdRegisterLocalInvalid(int cacheId,
273305
Index hashIndex,
274306
ItemPointer pointer)
275307
{
@@ -298,7 +330,8 @@ CacheIdRegisterLocalInvalid(Index cacheId,
298330
* --------------------------------
299331
*/
300332
static void
301-
CacheIdRegisterLocalRollback(Index cacheId, Index hashIndex,
333+
CacheIdRegisterLocalRollback(int cacheId,
334+
Index hashIndex,
302335
ItemPointer pointer)
303336
{
304337

@@ -477,7 +510,7 @@ CacheIdInvalidate(Index cacheId,
477510
* --------------------------------
478511
*/
479512
static void
480-
ResetSystemCaches()
513+
ResetSystemCaches(void)
481514
{
482515
ResetSystemCache();
483516
RelationCacheInvalidate();
@@ -585,13 +618,13 @@ InvalidationMessageCacheInvalidate(InvalidationMessage message)
585618
}
586619

587620
/* --------------------------------
588-
* RelationInvalidateRelationCache
621+
* PrepareToInvalidateRelationCache
589622
* --------------------------------
590623
*/
591624
static void
592-
RelationInvalidateRelationCache(Relation relation,
593-
HeapTuple tuple,
594-
void (*function) ())
625+
PrepareToInvalidateRelationCache(Relation relation,
626+
HeapTuple tuple,
627+
void (*function) (Oid, Oid))
595628
{
596629
Oid relationId;
597630
Oid objectId;
@@ -614,7 +647,7 @@ RelationInvalidateRelationCache(Relation relation,
614647
return;
615648

616649
/* ----------------
617-
* can't handle immediate relation descriptor invalidation
650+
* register the relcache-invalidation action in the appropriate list
618651
* ----------------
619652
*/
620653
Assert(PointerIsValid(function));
@@ -629,11 +662,9 @@ RelationInvalidateRelationCache(Relation relation,
629662
*
630663
* Note:
631664
* This should be called as the first step in processing a transaction.
632-
* This should be called while waiting for a query from the front end
633-
* when other backends are active.
634665
*/
635666
void
636-
DiscardInvalid()
667+
DiscardInvalid(void)
637668
{
638669
/* ----------------
639670
* debugging stuff
@@ -694,7 +725,8 @@ RegisterInvalid(bool send)
694725
* Causes invalidation immediately for the next command of the transaction.
695726
*
696727
* Note:
697-
* This should be called in time of CommandCounterIncrement().
728+
* This should be called during CommandCounterIncrement(),
729+
* after we have advanced the command ID.
698730
*/
699731
void
700732
ImmediateLocalInvalidation(bool send)
@@ -735,28 +767,29 @@ ImmediateLocalInvalidation(bool send)
735767
}
736768

737769
/*
738-
* InvokeHeapTupleInvalidation
770+
* PrepareForTupleInvalidation
739771
* Invoke functions for the tuple which register invalidation
740772
* of catalog/relation cache.
741773
* Note:
742774
* Assumes object id is valid.
743775
* Assumes tuple is valid.
744776
*/
745777
#ifdef INVALIDDEBUG
746-
#define InvokeHeapTupleInvalidation_DEBUG1 \
778+
#define PrepareForTupleInvalidation_DEBUG1 \
747779
elog(DEBUG, "%s(%s, [%d,%d])", \
748780
funcname,\
749781
RelationGetPhysicalRelationName(relation), \
750782
ItemPointerGetBlockNumber(&tuple->t_self), \
751783
ItemPointerGetOffsetNumber(&tuple->t_self))
752784
#else
753-
#define InvokeHeapTupleInvalidation_DEBUG1
785+
#define PrepareForTupleInvalidation_DEBUG1
754786
#endif /* defined(INVALIDDEBUG) */
755787

756788
static void
757-
InvokeHeapTupleInvalidation(Relation relation, HeapTuple tuple,
758-
void (*CacheIdRegisterFunc) (),
759-
void (*RelationIdRegisterFunc) (),
789+
PrepareForTupleInvalidation(Relation relation, HeapTuple tuple,
790+
void (*CacheIdRegisterFunc) (int, Index,
791+
ItemPointer),
792+
void (*RelationIdRegisterFunc) (Oid, Oid),
760793
const char *funcname)
761794
{
762795
/* ----------------
@@ -768,8 +801,11 @@ InvokeHeapTupleInvalidation(Relation relation, HeapTuple tuple,
768801

769802
if (IsBootstrapProcessingMode())
770803
return;
804+
771805
/* ----------------
772-
* this only works for system relations now
806+
* We only need to worry about invalidation for tuples that are in
807+
* system relations; user-relation tuples are never in catcaches
808+
* and can't affect the relcache either.
773809
* ----------------
774810
*/
775811
if (!IsSystemRelationName(NameStr(RelationGetForm(relation)->relname)))
@@ -779,37 +815,38 @@ InvokeHeapTupleInvalidation(Relation relation, HeapTuple tuple,
779815
* debugging stuff
780816
* ----------------
781817
*/
782-
InvokeHeapTupleInvalidation_DEBUG1;
818+
PrepareForTupleInvalidation_DEBUG1;
783819

784-
RelationInvalidateCatalogCacheTuple(relation, tuple,
785-
CacheIdRegisterFunc);
820+
PrepareToInvalidateCacheTuple(relation, tuple,
821+
CacheIdRegisterFunc);
786822

787-
RelationInvalidateRelationCache(relation, tuple,
788-
RelationIdRegisterFunc);
823+
PrepareToInvalidateRelationCache(relation, tuple,
824+
RelationIdRegisterFunc);
789825
}
790826

791827
/*
792828
* RelationInvalidateHeapTuple
793-
* Causes the given tuple in a relation to be invalidated.
829+
* Register the given tuple for invalidation at end of command
830+
* (ie, current command is outdating this tuple).
794831
*/
795832
void
796833
RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple)
797834
{
798-
InvokeHeapTupleInvalidation(relation, tuple,
835+
PrepareForTupleInvalidation(relation, tuple,
799836
CacheIdRegisterLocalInvalid,
800837
RelationIdRegisterLocalInvalid,
801838
"RelationInvalidateHeapTuple");
802839
}
803840

804841
/*
805842
* RelationMark4RollbackHeapTuple
806-
* keep the given tuple in a relation to be invalidated
807-
* in case of abort.
843+
* Register the given tuple for invalidation in case of abort
844+
* (ie, current command is creating this tuple).
808845
*/
809846
void
810847
RelationMark4RollbackHeapTuple(Relation relation, HeapTuple tuple)
811848
{
812-
InvokeHeapTupleInvalidation(relation, tuple,
849+
PrepareForTupleInvalidation(relation, tuple,
813850
CacheIdRegisterLocalRollback,
814851
RelationIdRegisterLocalRollback,
815852
"RelationMark4RollbackHeapTuple");

src/include/utils/catcache.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
1414
* Portions Copyright (c) 1994, Regents of the University of California
1515
*
16-
* $Id: catcache.h,v 1.29 2000/11/24 04:16:11 tgl Exp $
16+
* $Id: catcache.h,v 1.30 2001/01/05 22:54:37 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -95,7 +95,7 @@ extern void ResetSystemCache(void);
9595
extern void SystemCacheRelationFlushed(Oid relId);
9696
extern void CatalogCacheIdInvalidate(int cacheId, Index hashIndex,
9797
ItemPointer pointer);
98-
extern void RelationInvalidateCatalogCacheTuple(Relation relation,
98+
extern void PrepareToInvalidateCacheTuple(Relation relation,
9999
HeapTuple tuple,
100100
void (*function) (int, Index, ItemPointer));
101101

0 commit comments

Comments
 (0)