Skip to content

Commit b5282aa

Browse files
committed
Revise sinval code to remove no-longer-used tuple TID from inval messages.
This requires adjusting the API for syscache callback functions: they now get a hash value, not a TID, to identify the target tuple. Most of them weren't paying any attention to that argument anyway, but plancache did require a small amount of fixing. Also, improve performance a trifle by avoiding sending duplicate inval messages when a heap_update isn't changing the catcache lookup columns.
1 parent 632ae68 commit b5282aa

File tree

19 files changed

+210
-211
lines changed

19 files changed

+210
-211
lines changed

src/backend/access/heap/heapam.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,7 +2028,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
20282028
* the heaptup data structure is all in local memory, not in the shared
20292029
* buffer.
20302030
*/
2031-
CacheInvalidateHeapTuple(relation, heaptup);
2031+
CacheInvalidateHeapTuple(relation, heaptup, NULL);
20322032

20332033
pgstat_count_heap_insert(relation);
20342034

@@ -2354,7 +2354,7 @@ heap_delete(Relation relation, ItemPointer tid,
23542354
* boundary. We have to do this before releasing the buffer because we
23552355
* need to look at the contents of the tuple.
23562356
*/
2357-
CacheInvalidateHeapTuple(relation, &tp);
2357+
CacheInvalidateHeapTuple(relation, &tp, NULL);
23582358

23592359
/* Now we can release the buffer */
23602360
ReleaseBuffer(buffer);
@@ -2930,10 +2930,13 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
29302930

29312931
/*
29322932
* Mark old tuple for invalidation from system caches at next command
2933-
* boundary. We have to do this before releasing the buffer because we
2934-
* need to look at the contents of the tuple.
2933+
* boundary, and mark the new tuple for invalidation in case we abort.
2934+
* We have to do this before releasing the buffer because oldtup is in
2935+
* the buffer. (heaptup is all in local memory, but it's necessary to
2936+
* process both tuple versions in one call to inval.c so we can avoid
2937+
* redundant sinval messages.)
29352938
*/
2936-
CacheInvalidateHeapTuple(relation, &oldtup);
2939+
CacheInvalidateHeapTuple(relation, &oldtup, heaptup);
29372940

29382941
/* Now we can release the buffer(s) */
29392942
if (newbuf != buffer)
@@ -2944,14 +2947,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
29442947
if (BufferIsValid(vmbuffer))
29452948
ReleaseBuffer(vmbuffer);
29462949

2947-
/*
2948-
* If new tuple is cachable, mark it for invalidation from the caches in
2949-
* case we abort. Note it is OK to do this after releasing the buffer,
2950-
* because the heaptup data structure is all in local memory, not in the
2951-
* shared buffer.
2952-
*/
2953-
CacheInvalidateHeapTuple(relation, heaptup);
2954-
29552950
/*
29562951
* Release the lmgr tuple lock, if we had it.
29572952
*/
@@ -3659,9 +3654,14 @@ heap_inplace_update(Relation relation, HeapTuple tuple)
36593654

36603655
UnlockReleaseBuffer(buffer);
36613656

3662-
/* Send out shared cache inval if necessary */
3657+
/*
3658+
* Send out shared cache inval if necessary. Note that because we only
3659+
* pass the new version of the tuple, this mustn't be used for any
3660+
* operations that could change catcache lookup keys. But we aren't
3661+
* bothering with index updates either, so that's true a fortiori.
3662+
*/
36633663
if (!IsBootstrapProcessingMode())
3664-
CacheInvalidateHeapTuple(relation, tuple);
3664+
CacheInvalidateHeapTuple(relation, tuple, NULL);
36653665
}
36663666

36673667

src/backend/catalog/namespace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ static void recomputeNamespacePath(void);
192192
static void InitTempTableNamespace(void);
193193
static void RemoveTempRelations(Oid tempNamespaceId);
194194
static void RemoveTempRelationsCallback(int code, Datum arg);
195-
static void NamespaceCallback(Datum arg, int cacheid, ItemPointer tuplePtr);
195+
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue);
196196
static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
197197
int **argnumbers);
198198

@@ -3750,7 +3750,7 @@ InitializeSearchPath(void)
37503750
* Syscache inval callback function
37513751
*/
37523752
static void
3753-
NamespaceCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
3753+
NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
37543754
{
37553755
/* Force search path to be recomputed on next use */
37563756
baseSearchPathValid = false;

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -964,8 +964,7 @@ _copyPlanInvalItem(PlanInvalItem *from)
964964
PlanInvalItem *newnode = makeNode(PlanInvalItem);
965965

966966
COPY_SCALAR_FIELD(cacheId);
967-
/* tupleId isn't really a "scalar", but this works anyway */
968-
COPY_SCALAR_FIELD(tupleId);
967+
COPY_SCALAR_FIELD(hashValue);
969968

970969
return newnode;
971970
}

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -845,9 +845,7 @@ _outPlanInvalItem(StringInfo str, PlanInvalItem *node)
845845
WRITE_NODE_TYPE("PLANINVALITEM");
846846

847847
WRITE_INT_FIELD(cacheId);
848-
appendStringInfo(str, " :tupleId (%u,%u)",
849-
ItemPointerGetBlockNumber(&node->tupleId),
850-
ItemPointerGetOffsetNumber(&node->tupleId));
848+
WRITE_UINT_FIELD(hashValue);
851849
}
852850

853851
/*****************************************************************************

src/backend/optimizer/plan/setrefs.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
#include "postgres.h"
1717

18+
#include "access/hash.h"
1819
#include "access/transam.h"
1920
#include "catalog/pg_type.h"
2021
#include "nodes/makefuncs.h"
@@ -1751,25 +1752,21 @@ record_plan_function_dependency(PlannerGlobal *glob, Oid funcid)
17511752
*/
17521753
if (funcid >= (Oid) FirstBootstrapObjectId)
17531754
{
1754-
HeapTuple func_tuple;
1755-
PlanInvalItem *inval_item;
1756-
1757-
func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1758-
if (!HeapTupleIsValid(func_tuple))
1759-
elog(ERROR, "cache lookup failed for function %u", funcid);
1760-
1761-
inval_item = makeNode(PlanInvalItem);
1755+
PlanInvalItem *inval_item = makeNode(PlanInvalItem);
17621756

17631757
/*
1764-
* It would work to use any syscache on pg_proc, but plancache.c
1765-
* expects us to use PROCOID.
1758+
* It would work to use any syscache on pg_proc, but the easiest is
1759+
* PROCOID since we already have the function's OID at hand. Note
1760+
* that plancache.c knows we use PROCOID. Also, we're perhaps
1761+
* assuming more than we should about how CatalogCacheComputeHashValue
1762+
* computes hash values...
17661763
*/
17671764
inval_item->cacheId = PROCOID;
1768-
inval_item->tupleId = func_tuple->t_self;
1765+
inval_item->hashValue =
1766+
DatumGetUInt32(DirectFunctionCall1(hashoid,
1767+
ObjectIdGetDatum(funcid)));
17691768

17701769
glob->invalItems = lappend(glob->invalItems, inval_item);
1771-
1772-
ReleaseSysCache(func_tuple);
17731770
}
17741771
}
17751772

src/backend/optimizer/util/predtest.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static bool list_member_strip(List *list, Expr *datum);
101101
static bool btree_predicate_proof(Expr *predicate, Node *clause,
102102
bool refute_it);
103103
static Oid get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it);
104-
static void InvalidateOprProofCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr);
104+
static void InvalidateOprProofCacheCallBack(Datum arg, int cacheid, uint32 hashvalue);
105105

106106

107107
/*
@@ -1738,7 +1738,7 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
17381738
* Callback for pg_amop inval events
17391739
*/
17401740
static void
1741-
InvalidateOprProofCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr)
1741+
InvalidateOprProofCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
17421742
{
17431743
HASH_SEQ_STATUS status;
17441744
OprProofCacheEntry *hentry;

src/backend/parser/parse_oper.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static bool make_oper_cache_key(OprCacheKey *key, List *opname,
7979
Oid ltypeId, Oid rtypeId);
8080
static Oid find_oper_cache_entry(OprCacheKey *key);
8181
static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid);
82-
static void InvalidateOprCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr);
82+
static void InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue);
8383

8484

8585
/*
@@ -1104,7 +1104,7 @@ make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
11041104
* Callback for pg_operator and pg_cast inval events
11051105
*/
11061106
static void
1107-
InvalidateOprCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr)
1107+
InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
11081108
{
11091109
HASH_SEQ_STATUS status;
11101110
OprCacheEntry *hentry;

src/backend/utils/adt/acl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static AclMode convert_tablespace_priv_string(text *priv_type_text);
112112
static AclMode convert_role_priv_string(text *priv_type_text);
113113
static AclResult pg_role_aclcheck(Oid role_oid, Oid roleid, AclMode mode);
114114

115-
static void RoleMembershipCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr);
115+
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue);
116116
static Oid get_role_oid_or_public(const char *rolname);
117117

118118

@@ -4355,7 +4355,7 @@ initialize_acl(void)
43554355
* Syscache inval callback function
43564356
*/
43574357
static void
4358-
RoleMembershipCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
4358+
RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
43594359
{
43604360
/* Force membership caches to be recomputed on next use */
43614361
cached_privs_role = InvalidOid;

src/backend/utils/cache/attoptcache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ typedef struct
5353
* query execution), this seems OK.
5454
*/
5555
static void
56-
InvalidateAttoptCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
56+
InvalidateAttoptCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
5757
{
5858
HASH_SEQ_STATUS status;
5959
AttoptCacheEntry *attopt;

src/backend/utils/cache/catcache.c

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -435,21 +435,14 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
435435
* target tuple that has to be invalidated has a different TID than it
436436
* did when the event was created. So now we just compare hash values and
437437
* accept the small risk of unnecessary invalidations due to false matches.
438-
* (The ItemPointer argument is therefore useless and should get removed.)
439438
*
440439
* This routine is only quasi-public: it should only be used by inval.c.
441440
*/
442441
void
443-
CatalogCacheIdInvalidate(int cacheId,
444-
uint32 hashValue,
445-
ItemPointer pointer)
442+
CatalogCacheIdInvalidate(int cacheId, uint32 hashValue)
446443
{
447444
CatCache *ccp;
448445

449-
/*
450-
* sanity checks
451-
*/
452-
Assert(ItemPointerIsValid(pointer));
453446
CACHE1_elog(DEBUG2, "CatalogCacheIdInvalidate: called");
454447

455448
/*
@@ -699,7 +692,7 @@ CatalogCacheFlushCatalog(Oid catId)
699692
ResetCatalogCache(cache);
700693

701694
/* Tell inval.c to call syscache callbacks for this cache */
702-
CallSyscacheCallbacks(cache->id, NULL);
695+
CallSyscacheCallbacks(cache->id, 0);
703696
}
704697
}
705698

@@ -1708,11 +1701,16 @@ build_dummy_tuple(CatCache *cache, int nkeys, ScanKey skeys)
17081701
* The lists of tuples that need to be flushed are kept by inval.c. This
17091702
* routine is a helper routine for inval.c. Given a tuple belonging to
17101703
* the specified relation, find all catcaches it could be in, compute the
1711-
* correct hash value for each such catcache, and call the specified function
1712-
* to record the cache id, hash value, and tuple ItemPointer in inval.c's
1713-
* lists. CatalogCacheIdInvalidate will be called later, if appropriate,
1704+
* correct hash value for each such catcache, and call the specified
1705+
* function to record the cache id and hash value in inval.c's lists.
1706+
* CatalogCacheIdInvalidate will be called later, if appropriate,
17141707
* using the recorded information.
17151708
*
1709+
* For an insert or delete, tuple is the target tuple and newtuple is NULL.
1710+
* For an update, we are called just once, with tuple being the old tuple
1711+
* version and newtuple the new version. We should make two list entries
1712+
* if the tuple's hash value changed, but only one if it didn't.
1713+
*
17161714
* Note that it is irrelevant whether the given tuple is actually loaded
17171715
* into the catcache at the moment. Even if it's not there now, it might
17181716
* be by the end of the command, or there might be a matching negative entry
@@ -1727,7 +1725,8 @@ build_dummy_tuple(CatCache *cache, int nkeys, ScanKey skeys)
17271725
void
17281726
PrepareToInvalidateCacheTuple(Relation relation,
17291727
HeapTuple tuple,
1730-
void (*function) (int, uint32, ItemPointer, Oid))
1728+
HeapTuple newtuple,
1729+
void (*function) (int, uint32, Oid))
17311730
{
17321731
CatCache *ccp;
17331732
Oid reloid;
@@ -1747,24 +1746,37 @@ PrepareToInvalidateCacheTuple(Relation relation,
17471746
/* ----------------
17481747
* for each cache
17491748
* if the cache contains tuples from the specified relation
1750-
* compute the tuple's hash value in this cache,
1749+
* compute the tuple's hash value(s) in this cache,
17511750
* and call the passed function to register the information.
17521751
* ----------------
17531752
*/
17541753

17551754
for (ccp = CacheHdr->ch_caches; ccp; ccp = ccp->cc_next)
17561755
{
1756+
uint32 hashvalue;
1757+
Oid dbid;
1758+
17571759
if (ccp->cc_reloid != reloid)
17581760
continue;
17591761

17601762
/* Just in case cache hasn't finished initialization yet... */
17611763
if (ccp->cc_tupdesc == NULL)
17621764
CatalogCacheInitializeCache(ccp);
17631765

1764-
(*function) (ccp->id,
1765-
CatalogCacheComputeTupleHashValue(ccp, tuple),
1766-
&tuple->t_self,
1767-
ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId);
1766+
hashvalue = CatalogCacheComputeTupleHashValue(ccp, tuple);
1767+
dbid = ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId;
1768+
1769+
(*function) (ccp->id, hashvalue, dbid);
1770+
1771+
if (newtuple)
1772+
{
1773+
uint32 newhashvalue;
1774+
1775+
newhashvalue = CatalogCacheComputeTupleHashValue(ccp, newtuple);
1776+
1777+
if (newhashvalue != hashvalue)
1778+
(*function) (ccp->id, newhashvalue, dbid);
1779+
}
17681780
}
17691781
}
17701782

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy