171#define CatCacheMsgs 0
172#define RelCacheMsgs 1
191#define SetSubGroupToFollow(targetgroup, priorgroup, subgroup) \
193 (targetgroup)->firstmsg[subgroup] = \
194 (targetgroup)->nextmsg[subgroup] = \
195 (priorgroup)->nextmsg[subgroup]; \
198#define SetGroupToFollow(targetgroup, priorgroup) \
200 SetSubGroupToFollow(targetgroup, priorgroup, CatCacheMsgs); \
201 SetSubGroupToFollow(targetgroup, priorgroup, RelCacheMsgs); \
204#define NumMessagesInSubGroup(group, subgroup) \
205 ((group)->nextmsg[subgroup] - (group)->firstmsg[subgroup])
207#define NumMessagesInGroup(group) \
208 (NumMessagesInSubGroup(group, CatCacheMsgs) + \
209 NumMessagesInSubGroup(group, RelCacheMsgs))
272#define MAX_SYSCACHE_CALLBACKS 64
273#define MAX_RELCACHE_CALLBACKS 10
274#define MAX_RELSYNC_CALLBACKS 10
324 int nextindex = group->
nextmsg[subgroup];
328 if (ima->
msgs == NULL)
342 int reqsize = 2 * ima->
maxmsgs;
351 ima->
msgs[nextindex] = *msg;
384#define ProcessMessageSubGroup(group, subgroup, codeFragment) \
386 int _msgindex = (group)->firstmsg[subgroup]; \
387 int _endmsg = (group)->nextmsg[subgroup]; \
388 for (; _msgindex < _endmsg; _msgindex++) \
390 SharedInvalidationMessage *msg = \
391 &InvalMessageArrays[subgroup].msgs[_msgindex]; \
402#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment) \
404 int n = NumMessagesInSubGroup(group, subgroup); \
406 SharedInvalidationMessage *msgs = \
407 &InvalMessageArrays[subgroup].msgs[(group)->firstmsg[subgroup]]; \
612 cacheId, hashValue, dbId);
716 elog(
ERROR,
"cannot start a subtransaction when there are unprocessed inval messages");
900 elog(
FATAL,
"unrecognized SI message ID: %d", msg->
id);
959#ifdef DISCARD_CACHES_ENABLED
1006 bool *RelcacheInitFileInval)
1015 *RelcacheInitFileInval =
false;
1048 (memcpy(msgarray + nmsgs,
1054 (memcpy(msgarray + nmsgs,
1060 (memcpy(msgarray + nmsgs,
1066 (memcpy(msgarray + nmsgs,
1070 Assert(nmsgs == nummsgs);
1082 bool *RelcacheInitFileInval)
1091 *RelcacheInitFileInval =
false;
1104 (memcpy(msgarray + nmsgs,
1110 (memcpy(msgarray + nmsgs,
1114 Assert(nmsgs == nummsgs);
1129 int nmsgs,
bool RelcacheInitFileInval,
1135 elog(
DEBUG4,
"replaying commit with %d messages%s", nmsgs,
1136 (RelcacheInitFileInval ?
" and relcache file invalidation" :
""));
1138 if (RelcacheInitFileInval)
1140 elog(
DEBUG4,
"removing relcache init files for database %u", dbid);
1163 if (RelcacheInitFileInval)
1459 info = prepare_callback();
1482 if (tupleRelId == RelationRelationId)
1486 relationId = classtup->oid;
1487 if (classtup->relisshared)
1492 else if (tupleRelId == AttributeRelationId)
1496 relationId = atttup->attrelid;
1510 else if (tupleRelId == IndexRelationId)
1520 relationId = indextup->indexrelid;
1523 else if (tupleRelId == ConstraintRelationId)
1531 if (constrtup->contype == CONSTRAINT_FOREIGN &&
1534 relationId = constrtup->conrelid;
1608 databaseId, catalogId);
1627 if (relation->
rd_rel->relisshared)
1633 databaseId, relationId);
1661 relationId = classtup->oid;
1662 if (classtup->relisshared)
1667 databaseId, relationId);
1683 elog(
ERROR,
"cache lookup failed for relation %u", relid);
1747 "MAX_BACKEND_BITS is too big for inval.c");
1780 msg.
rm.
dbId = databaseId;
1806 if (cacheid < 0 || cacheid >= SysCacheSize)
1807 elog(
FATAL,
"invalid cache ID: %d", cacheid);
1809 elog(
FATAL,
"out of syscache_callback_list slots");
1848 elog(
FATAL,
"out of relcache_callback_list slots");
1869 elog(
FATAL,
"out of relsync_callback_list slots");
1888 if (cacheid < 0 || cacheid >= SysCacheSize)
1889 elog(
ERROR,
"invalid cache ID: %d", cacheid);
1897 ccitem->
function(ccitem->
arg, cacheid, hashvalue);
1898 i = ccitem->
link - 1;
1942 xlrec.
nmsgs = nmsgs;
#define StaticAssertStmt(condition, errmessage)
#define OidIsValid(objectId)
bool IsToastRelation(Relation relation)
bool IsCatalogRelation(Relation relation)
bool IsSharedRelation(Oid relationId)
void PrepareToInvalidateCacheTuple(Relation relation, HeapTuple tuple, HeapTuple newtuple, void(*function)(int, uint32, Oid, void *), void *context)
void CatalogCacheFlushCatalog(Oid catId)
void ResetCatalogCachesExt(bool debug_discard)
static int recursion_depth
volatile uint32 CritSectionCount
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
#define INJECTION_POINT(name)
void PostPrepare_Inval(void)
void InvalidateSystemCachesExtended(bool debug_discard)
void CallRelSyncCallbacks(Oid relid)
static void AddCatcacheInvalidationMessage(InvalidationMsgsGroup *group, int id, uint32 hashValue, Oid dbId)
void CacheInvalidateRelSyncAll(void)
static void AddCatalogInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid catId)
static void RegisterRelcacheInvalidation(InvalidationInfo *info, Oid dbId, Oid relId)
static int relcache_callback_count
#define NumMessagesInGroup(group)
static void AddRelcacheInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid relId)
static int relsync_callback_count
static void AddRelsyncInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid relId)
void LogLogicalInvalidations(void)
void CacheInvalidateHeapTupleInplace(Relation relation, HeapTuple tuple, HeapTuple newtuple)
void AcceptInvalidationMessages(void)
static void ProcessInvalidationMessages(InvalidationMsgsGroup *group, void(*func)(SharedInvalidationMessage *msg))
void CacheInvalidateRelmap(Oid databaseId)
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
struct TransInvalidationInfo TransInvalidationInfo
static void RegisterCatcacheInvalidation(int cacheId, uint32 hashValue, Oid dbId, void *context)
void CacheInvalidateCatalog(Oid catalogId)
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
static struct RELSYNCCALLBACK relsync_callback_list[MAX_RELSYNC_CALLBACKS]
static InvalidationInfo * inplaceInvalInfo
static void AppendInvalidationMessageSubGroup(InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src, int subgroup)
static void RegisterSnapshotInvalidation(InvalidationInfo *info, Oid dbId, Oid relId)
struct InvalidationInfo InvalidationInfo
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
static TransInvalidationInfo * transInvalInfo
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
#define ProcessMessageSubGroup(group, subgroup, codeFragment)
void CacheInvalidateRelcache(Relation relation)
static InvalidationInfo * PrepareInvalidationState(void)
static void AppendInvalidationMessages(InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src)
#define MAX_RELSYNC_CALLBACKS
static void ProcessInvalidationMessagesMulti(InvalidationMsgsGroup *group, void(*func)(const SharedInvalidationMessage *msgs, int n))
int inplaceGetInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
void CacheInvalidateRelcacheByRelid(Oid relid)
void InvalidateSystemCaches(void)
void AtEOXact_Inval(bool isCommit)
#define MAX_SYSCACHE_CALLBACKS
void CacheInvalidateSmgr(RelFileLocatorBackend rlocator)
#define SetGroupToFollow(targetgroup, priorgroup)
void AtEOSubXact_Inval(bool isCommit)
static void AddSnapshotInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid relId)
static int16 syscache_callback_links[SysCacheSize]
static void AddInvalidationMessage(InvalidationMsgsGroup *group, int subgroup, const SharedInvalidationMessage *msg)
void PreInplace_Inval(void)
struct InvalMessageArray InvalMessageArray
void CommandEndInvalidationMessages(void)
void AtInplace_Inval(void)
static void RegisterCatalogInvalidation(InvalidationInfo *info, Oid dbId, Oid catId)
#define MAX_RELCACHE_CALLBACKS
void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, Datum arg)
void CacheRegisterRelSyncCallback(RelSyncCallbackFunction func, Datum arg)
void ForgetInplace_Inval(void)
#define SetSubGroupToFollow(targetgroup, priorgroup, subgroup)
struct InvalidationMsgsGroup InvalidationMsgsGroup
void CacheInvalidateRelSync(Oid relid)
static InvalidationInfo * PrepareInplaceInvalidationState(void)
void CacheInvalidateHeapTuple(Relation relation, HeapTuple tuple, HeapTuple newtuple)
static void CacheInvalidateHeapTupleCommon(Relation relation, HeapTuple tuple, HeapTuple newtuple, InvalidationInfo *(*prepare_callback)(void))
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
static InvalMessageArray InvalMessageArrays[2]
static int syscache_callback_count
static void RegisterRelsyncInvalidation(InvalidationInfo *info, Oid dbId, Oid relId)
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
void CacheInvalidateRelcacheAll(void)
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
void(* SyscacheCallbackFunction)(Datum arg, int cacheid, uint32 hashvalue)
void(* RelcacheCallbackFunction)(Datum arg, Oid relid)
void(* RelSyncCallbackFunction)(Datum arg, Oid relid)
void * MemoryContextAlloc(MemoryContext context, Size size)
void * MemoryContextAllocZero(MemoryContext context, Size size)
MemoryContext TopTransactionContext
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurTransactionContext
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
#define IsBootstrapProcessingMode()
FormData_pg_attribute * Form_pg_attribute
FormData_pg_class * Form_pg_class
FormData_pg_constraint * Form_pg_constraint
FormData_pg_index * Form_pg_index
static Datum ObjectIdGetDatum(Oid X)
#define MAX_BACKENDS_BITS
#define RelationGetRelid(relation)
void RelationCacheInvalidate(bool debug_discard)
void RelationCacheInitFilePostInvalidate(void)
void RelationCacheInitFilePreInvalidate(void)
bool RelationIdIsInInitFile(Oid relationId)
void RelationCacheInvalidateEntry(Oid relationId)
void RelationMapInvalidate(bool shared)
char * GetDatabasePath(Oid dbOid, Oid spcOid)
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
void ReceiveSharedInvalidMessages(void(*invalFunction)(SharedInvalidationMessage *msg), void(*resetFunction)(void))
#define SHAREDINVALCATALOG_ID
#define SHAREDINVALRELSYNC_ID
#define SHAREDINVALSMGR_ID
#define SHAREDINVALSNAPSHOT_ID
#define SHAREDINVALRELCACHE_ID
#define SHAREDINVALRELMAP_ID
void smgrreleaserellocator(RelFileLocatorBackend rlocator)
void InvalidateCatalogSnapshot(void)
SharedInvalidationMessage * msgs
bool RelcacheInitFileInval
InvalidationMsgsGroup CurrentCmdInvalidMsgs
RelcacheCallbackFunction function
RelSyncCallbackFunction function
SyscacheCallbackFunction function
struct TransInvalidationInfo * parent
struct InvalidationInfo ii
InvalidationMsgsGroup PriorCmdInvalidMsgs
void SysCacheInvalidate(int cacheId, uint32 hashValue)
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
bool RelationInvalidatesSnapshotsOnly(Oid relid)
SharedInvalCatcacheMsg cc
SharedInvalRelcacheMsg rc
SharedInvalCatalogMsg cat
SharedInvalSnapshotMsg sn
int GetCurrentTransactionNestLevel(void)
bool IsTransactionState(void)
CommandId GetCurrentCommandId(bool used)
#define MinSizeOfXactInvals
#define XLOG_XACT_INVALIDATIONS
#define XLogLogicalInfoActive()
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterData(const void *data, uint32 len)
void XLogBeginInsert(void)