#include "postgres.h"
#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "miscadmin.h"
#include "storage/sinval.h"
#include "storage/smgr.h"
#include "utils/catcache.h"
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/relmapper.h"
#include "utils/syscache.h"
Go to the source code of this file.
#define FIRSTCHUNKSIZE 32 |
Referenced by AddInvalidationMessage().
#define MAX_RELCACHE_CALLBACKS 5 |
Definition at line 180 of file inval.c.
Referenced by CacheRegisterRelcacheCallback().
#define MAX_SYSCACHE_CALLBACKS 32 |
Definition at line 179 of file inval.c.
Referenced by CacheRegisterSyscacheCallback().
#define ProcessMessageList | ( | listHdr, | ||
codeFragment | ||||
) |
do { \ InvalidationChunk *_chunk; \ for (_chunk = (listHdr); _chunk != NULL; _chunk = _chunk->next) \ { \ int _cindex; \ for (_cindex = 0; _cindex < _chunk->nitems; _cindex++) \ { \ SharedInvalidationMessage *msg = &_chunk->msgs[_cindex]; \ codeFragment; \ } \ } \ } while (0)
Definition at line 281 of file inval.c.
Referenced by AddRelcacheInvalidationMessage(), and ProcessInvalidationMessages().
#define ProcessMessageListMulti | ( | listHdr, | ||
codeFragment | ||||
) |
do { \ InvalidationChunk *_chunk; \ for (_chunk = (listHdr); _chunk != NULL; _chunk = _chunk->next) \ { \ SharedInvalidationMessage *msgs = _chunk->msgs; \ int n = _chunk->nitems; \ codeFragment; \ } \ } while (0)
Definition at line 301 of file inval.c.
Referenced by ProcessInvalidationMessagesMulti().
typedef struct InvalidationChunk InvalidationChunk |
typedef struct InvalidationListHeader InvalidationListHeader |
typedef struct TransInvalidationInfo TransInvalidationInfo |
void AcceptInvalidationMessages | ( | void | ) |
Definition at line 588 of file inval.c.
References InvalidateSystemCaches(), LocalExecuteInvalidationMessage(), and ReceiveSharedInvalidMessages().
Referenced by AtStart_Cache(), ConditionalLockRelation(), ConditionalLockRelationOid(), LockDatabaseObject(), LockRelation(), LockRelationOid(), LockSharedObject(), ProcessCatchupEvent(), RangeVarGetRelidExtended(), relation_openrv(), relation_openrv_extended(), RemoveRelations(), and write_relcache_init_file().
{ ReceiveSharedInvalidMessages(LocalExecuteInvalidationMessage, InvalidateSystemCaches); /* * Test code to force cache flushes anytime a flush could happen. * * If used with CLOBBER_FREED_MEMORY, CLOBBER_CACHE_ALWAYS provides a * fairly thorough test that the system contains no cache-flush hazards. * However, it also makes the system unbelievably slow --- the regression * tests take about 100 times longer than normal. * * If you're a glutton for punishment, try CLOBBER_CACHE_RECURSIVELY. This * slows things by at least a factor of 10000, so I wouldn't suggest * trying to run the entire regression tests that way. It's useful to try * a few simple tests, to make sure that cache reload isn't subject to * internal cache-flush hazards, but after you've done a few thousand * recursive reloads it's unlikely you'll learn more. */ #if defined(CLOBBER_CACHE_ALWAYS) { static bool in_recursion = false; if (!in_recursion) { in_recursion = true; InvalidateSystemCaches(); in_recursion = false; } } #elif defined(CLOBBER_CACHE_RECURSIVELY) InvalidateSystemCaches(); #endif }
static void AddCatalogInvalidationMessage | ( | InvalidationListHeader * | hdr, | |
Oid | dbId, | |||
Oid | catId | |||
) | [static] |
Definition at line 341 of file inval.c.
References AddInvalidationMessage(), SharedInvalidationMessage::cat, SharedInvalCatalogMsg::catId, InvalidationListHeader::cclist, SharedInvalCatalogMsg::dbId, and SharedInvalCatalogMsg::id.
Referenced by RegisterCatalogInvalidation().
{ SharedInvalidationMessage msg; msg.cat.id = SHAREDINVALCATALOG_ID; msg.cat.dbId = dbId; msg.cat.catId = catId; AddInvalidationMessage(&hdr->cclist, &msg); }
static void AddCatcacheInvalidationMessage | ( | InvalidationListHeader * | hdr, | |
int | id, | |||
uint32 | hashValue, | |||
Oid | dbId | |||
) | [static] |
Definition at line 325 of file inval.c.
References AddInvalidationMessage(), Assert, SharedInvalidationMessage::cc, InvalidationListHeader::cclist, SharedInvalCatcacheMsg::dbId, SharedInvalCatcacheMsg::hashValue, and SharedInvalCatcacheMsg::id.
Referenced by RegisterCatcacheInvalidation().
{ SharedInvalidationMessage msg; Assert(id < CHAR_MAX); msg.cc.id = (int8) id; msg.cc.dbId = dbId; msg.cc.hashValue = hashValue; AddInvalidationMessage(&hdr->cclist, &msg); }
static void AddInvalidationMessage | ( | InvalidationChunk ** | listHdr, | |
SharedInvalidationMessage * | msg | |||
) | [static] |
Definition at line 215 of file inval.c.
References CurTransactionContext, FIRSTCHUNKSIZE, InvalidationChunk::maxitems, MemoryContextAlloc(), InvalidationChunk::msgs, InvalidationChunk::next, InvalidationChunk::nitems, and NULL.
Referenced by AddCatalogInvalidationMessage(), AddCatcacheInvalidationMessage(), and AddRelcacheInvalidationMessage().
{ InvalidationChunk *chunk = *listHdr; if (chunk == NULL) { /* First time through; create initial chunk */ #define FIRSTCHUNKSIZE 32 chunk = (InvalidationChunk *) MemoryContextAlloc(CurTransactionContext, sizeof(InvalidationChunk) + (FIRSTCHUNKSIZE - 1) *sizeof(SharedInvalidationMessage)); chunk->nitems = 0; chunk->maxitems = FIRSTCHUNKSIZE; chunk->next = *listHdr; *listHdr = chunk; } else if (chunk->nitems >= chunk->maxitems) { /* Need another chunk; double size of last chunk */ int chunksize = 2 * chunk->maxitems; chunk = (InvalidationChunk *) MemoryContextAlloc(CurTransactionContext, sizeof(InvalidationChunk) + (chunksize - 1) *sizeof(SharedInvalidationMessage)); chunk->nitems = 0; chunk->maxitems = chunksize; chunk->next = *listHdr; *listHdr = chunk; } /* Okay, add message to current chunk */ chunk->msgs[chunk->nitems] = *msg; chunk->nitems++; }
static void AddRelcacheInvalidationMessage | ( | InvalidationListHeader * | hdr, | |
Oid | dbId, | |||
Oid | relId | |||
) | [static] |
Definition at line 356 of file inval.c.
References AddInvalidationMessage(), SharedInvalRelcacheMsg::dbId, SharedInvalRelcacheMsg::id, ProcessMessageList, SharedInvalidationMessage::rc, InvalidationListHeader::rclist, SharedInvalRelcacheMsg::relId, and SHAREDINVALRELCACHE_ID.
Referenced by RegisterRelcacheInvalidation().
{ SharedInvalidationMessage msg; /* Don't add a duplicate item */ /* We assume dbId need not be checked because it will never change */ ProcessMessageList(hdr->rclist, if (msg->rc.id == SHAREDINVALRELCACHE_ID && msg->rc.relId == relId) return); /* OK, add the item */ msg.rc.id = SHAREDINVALRELCACHE_ID; msg.rc.dbId = dbId; msg.rc.relId = relId; AddInvalidationMessage(&hdr->rclist, &msg); }
static void AppendInvalidationMessageList | ( | InvalidationChunk ** | destHdr, | |
InvalidationChunk ** | srcHdr | |||
) | [static] |
Definition at line 257 of file inval.c.
References InvalidationChunk::next, and NULL.
Referenced by AppendInvalidationMessages().
static void AppendInvalidationMessages | ( | InvalidationListHeader * | dest, | |
InvalidationListHeader * | src | |||
) | [static] |
Definition at line 380 of file inval.c.
References AppendInvalidationMessageList(), InvalidationListHeader::cclist, and InvalidationListHeader::rclist.
Referenced by AtEOSubXact_Inval(), AtEOXact_Inval(), and CommandEndInvalidationMessages().
{ AppendInvalidationMessageList(&dest->cclist, &src->cclist); AppendInvalidationMessageList(&dest->rclist, &src->rclist); }
void AtEOSubXact_Inval | ( | bool | isCommit | ) |
Definition at line 890 of file inval.c.
References AppendInvalidationMessages(), Assert, CommandEndInvalidationMessages(), GetCurrentTransactionNestLevel(), LocalExecuteInvalidationMessage(), TransInvalidationInfo::my_level, NULL, TransInvalidationInfo::parent, pfree(), TransInvalidationInfo::PriorCmdInvalidMsgs, ProcessInvalidationMessages(), and TransInvalidationInfo::RelcacheInitFileInval.
Referenced by AbortSubTransaction(), and CommitSubTransaction().
{ int my_level = GetCurrentTransactionNestLevel(); TransInvalidationInfo *myInfo = transInvalInfo; if (isCommit) { /* Must be at non-top of stack */ Assert(myInfo != NULL && myInfo->parent != NULL); Assert(myInfo->my_level == my_level); /* If CurrentCmdInvalidMsgs still has anything, fix it */ CommandEndInvalidationMessages(); /* Pass up my inval messages to parent */ AppendInvalidationMessages(&myInfo->parent->PriorCmdInvalidMsgs, &myInfo->PriorCmdInvalidMsgs); /* Pending relcache inval becomes parent's problem too */ if (myInfo->RelcacheInitFileInval) myInfo->parent->RelcacheInitFileInval = true; /* Pop the transaction state stack */ transInvalInfo = myInfo->parent; /* Need not free anything else explicitly */ pfree(myInfo); } else if (myInfo != NULL && myInfo->my_level == my_level) { /* Must be at non-top of stack */ Assert(myInfo->parent != NULL); ProcessInvalidationMessages(&myInfo->PriorCmdInvalidMsgs, LocalExecuteInvalidationMessage); /* Pop the transaction state stack */ transInvalInfo = myInfo->parent; /* Need not free anything else explicitly */ pfree(myInfo); } }
void AtEOXact_Inval | ( | bool | isCommit | ) |
Definition at line 834 of file inval.c.
References AppendInvalidationMessages(), Assert, TransInvalidationInfo::CurrentCmdInvalidMsgs, LocalExecuteInvalidationMessage(), NULL, TransInvalidationInfo::parent, TransInvalidationInfo::PriorCmdInvalidMsgs, ProcessInvalidationMessages(), ProcessInvalidationMessagesMulti(), RelationCacheInitFilePostInvalidate(), RelationCacheInitFilePreInvalidate(), TransInvalidationInfo::RelcacheInitFileInval, and SendSharedInvalidMessages().
Referenced by AbortTransaction(), CommitTransaction(), and PostPrepare_Inval().
{ if (isCommit) { /* Must be at top of stack */ Assert(transInvalInfo != NULL && transInvalInfo->parent == NULL); /* * Relcache init file invalidation requires processing both before and * after we send the SI messages. However, we need not do anything * unless we committed. */ if (transInvalInfo->RelcacheInitFileInval) RelationCacheInitFilePreInvalidate(); AppendInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs, &transInvalInfo->CurrentCmdInvalidMsgs); ProcessInvalidationMessagesMulti(&transInvalInfo->PriorCmdInvalidMsgs, SendSharedInvalidMessages); if (transInvalInfo->RelcacheInitFileInval) RelationCacheInitFilePostInvalidate(); } else if (transInvalInfo != NULL) { /* Must be at top of stack */ Assert(transInvalInfo->parent == NULL); ProcessInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs, LocalExecuteInvalidationMessage); } /* Need not free anything explicitly */ transInvalInfo = NULL; }
void AtStart_Inval | ( | void | ) |
Definition at line 629 of file inval.c.
References Assert, GetCurrentTransactionNestLevel(), MemoryContextAllocZero(), TransInvalidationInfo::my_level, NULL, numSharedInvalidMessagesArray, and TopTransactionContext.
Referenced by StartTransaction().
void AtSubStart_Inval | ( | void | ) |
Definition at line 663 of file inval.c.
References Assert, GetCurrentTransactionNestLevel(), MemoryContextAllocZero(), TransInvalidationInfo::my_level, NULL, TransInvalidationInfo::parent, and TopTransactionContext.
Referenced by StartSubTransaction().
{ TransInvalidationInfo *myInfo; Assert(transInvalInfo != NULL); myInfo = (TransInvalidationInfo *) MemoryContextAllocZero(TopTransactionContext, sizeof(TransInvalidationInfo)); myInfo->parent = transInvalInfo; myInfo->my_level = GetCurrentTransactionNestLevel(); transInvalInfo = myInfo; }
void CacheInvalidateCatalog | ( | Oid | catalogId | ) |
Definition at line 1082 of file inval.c.
References IsSharedRelation(), MyDatabaseId, and RegisterCatalogInvalidation().
Referenced by finish_heap_swap().
{ Oid databaseId; if (IsSharedRelation(catalogId)) databaseId = InvalidOid; else databaseId = MyDatabaseId; RegisterCatalogInvalidation(databaseId, catalogId); }
Definition at line 979 of file inval.c.
References AttributeRelationId, GETSTRUCT, HeapTupleGetOid, IndexRelationId, IsBootstrapProcessingMode, IsSystemRelation(), IsToastRelation(), MyDatabaseId, PrepareToInvalidateCacheTuple(), RegisterCatcacheInvalidation(), RegisterRelcacheInvalidation(), RelationGetRelid, and RelationRelationId.
Referenced by heap_delete(), heap_inplace_update(), heap_insert(), heap_multi_insert(), and heap_update().
{ Oid tupleRelId; Oid databaseId; Oid relationId; /* Do nothing during bootstrap */ if (IsBootstrapProcessingMode()) return; /* * 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 (!IsSystemRelation(relation)) return; /* * TOAST tuples can likewise be ignored here. Note that TOAST tables are * considered system relations so they are not filtered by the above test. */ if (IsToastRelation(relation)) return; /* * First let the catcache do its thing */ PrepareToInvalidateCacheTuple(relation, tuple, newtuple, RegisterCatcacheInvalidation); /* * Now, is this tuple one of the primary definers of a relcache entry? * * Note we ignore newtuple here; we assume an update cannot move a tuple * from being part of one relcache entry to being part of another. */ tupleRelId = RelationGetRelid(relation); if (tupleRelId == RelationRelationId) { Form_pg_class classtup = (Form_pg_class) GETSTRUCT(tuple); relationId = HeapTupleGetOid(tuple); if (classtup->relisshared) databaseId = InvalidOid; else databaseId = MyDatabaseId; } else if (tupleRelId == AttributeRelationId) { Form_pg_attribute atttup = (Form_pg_attribute) GETSTRUCT(tuple); relationId = atttup->attrelid; /* * KLUGE ALERT: we always send the relcache event with MyDatabaseId, * even if the rel in question is shared (which we can't easily tell). * This essentially means that only backends in this same database * will react to the relcache flush request. This is in fact * appropriate, since only those backends could see our pg_attribute * change anyway. It looks a bit ugly though. (In practice, shared * relations can't have schema changes after bootstrap, so we should * never come here for a shared rel anyway.) */ databaseId = MyDatabaseId; } else if (tupleRelId == IndexRelationId) { Form_pg_index indextup = (Form_pg_index) GETSTRUCT(tuple); /* * When a pg_index row is updated, we should send out a relcache inval * for the index relation. As above, we don't know the shared status * of the index, but in practice it doesn't matter since indexes of * shared catalogs can't have such updates. */ relationId = indextup->indexrelid; databaseId = MyDatabaseId; } else return; /* * Yes. We need to register a relcache invalidation event. */ RegisterRelcacheInvalidation(databaseId, relationId); }
void CacheInvalidateRelcache | ( | Relation | relation | ) |
Definition at line 1104 of file inval.c.
References MyDatabaseId, RelationData::rd_rel, RegisterRelcacheInvalidation(), and RelationGetRelid.
Referenced by _bt_getroot(), _bt_insertonpg(), _bt_newroot(), _bt_pagedel(), ATExecValidateConstraint(), EnableDisableRule(), EnableDisableTrigger(), index_drop(), reindex_index(), RemoveRewriteRuleById(), RemoveTriggerById(), RenameRewriteRule(), renametrig(), and SetRelationNumChecks().
{ Oid databaseId; Oid relationId; relationId = RelationGetRelid(relation); if (relation->rd_rel->relisshared) databaseId = InvalidOid; else databaseId = MyDatabaseId; RegisterRelcacheInvalidation(databaseId, relationId); }
void CacheInvalidateRelcacheByRelid | ( | Oid | relid | ) |
Definition at line 1144 of file inval.c.
References CacheInvalidateRelcacheByTuple(), elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RELOID, and SearchSysCache1.
Referenced by DefineIndex().
{ HeapTuple tup; tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for relation %u", relid); CacheInvalidateRelcacheByTuple(tup); ReleaseSysCache(tup); }
void CacheInvalidateRelcacheByTuple | ( | HeapTuple | classTuple | ) |
Definition at line 1123 of file inval.c.
References GETSTRUCT, HeapTupleGetOid, MyDatabaseId, and RegisterRelcacheInvalidation().
Referenced by CacheInvalidateRelcacheByRelid(), index_update_stats(), SetRelationHasSubclass(), SetRelationRuleStatus(), and swap_relation_files().
{ Form_pg_class classtup = (Form_pg_class) GETSTRUCT(classTuple); Oid databaseId; Oid relationId; relationId = HeapTupleGetOid(classTuple); if (classtup->relisshared) databaseId = InvalidOid; else databaseId = MyDatabaseId; RegisterRelcacheInvalidation(databaseId, relationId); }
void CacheInvalidateRelmap | ( | Oid | databaseId | ) |
Definition at line 1209 of file inval.c.
References SharedInvalRelmapMsg::dbId, SharedInvalRelmapMsg::id, SharedInvalidationMessage::rm, and SendSharedInvalidMessages().
Referenced by write_relmap_file().
{ SharedInvalidationMessage msg; msg.rm.id = SHAREDINVALRELMAP_ID; msg.rm.dbId = databaseId; SendSharedInvalidMessages(&msg, 1); }
void CacheInvalidateSmgr | ( | RelFileNodeBackend | rnode | ) |
Definition at line 1182 of file inval.c.
References RelFileNodeBackend::backend, SharedInvalSmgrMsg::backend_hi, SharedInvalSmgrMsg::backend_lo, SharedInvalSmgrMsg::id, RelFileNodeBackend::node, SharedInvalSmgrMsg::rnode, SendSharedInvalidMessages(), and SharedInvalidationMessage::sm.
Referenced by smgrdounlink(), smgrdounlinkall(), smgrdounlinkfork(), smgrtruncate(), and vm_extend().
{ SharedInvalidationMessage msg; msg.sm.id = SHAREDINVALSMGR_ID; msg.sm.backend_hi = rnode.backend >> 16; msg.sm.backend_lo = rnode.backend & 0xffff; msg.sm.rnode = rnode.node; SendSharedInvalidMessages(&msg, 1); }
void CacheRegisterRelcacheCallback | ( | RelcacheCallbackFunction | func, | |
Datum | arg | |||
) |
Definition at line 1257 of file inval.c.
References RELCACHECALLBACK::arg, elog, FATAL, RELCACHECALLBACK::function, MAX_RELCACHE_CALLBACKS, relcache_callback_count, and relcache_callback_list.
Referenced by InitPlanCache(), and lookup_type_cache().
{ if (relcache_callback_count >= MAX_RELCACHE_CALLBACKS) elog(FATAL, "out of relcache_callback_list slots"); relcache_callback_list[relcache_callback_count].function = func; relcache_callback_list[relcache_callback_count].arg = arg; ++relcache_callback_count; }
void CacheRegisterSyscacheCallback | ( | int | cacheid, | |
SyscacheCallbackFunction | func, | |||
Datum | arg | |||
) |
Definition at line 1233 of file inval.c.
References SYSCACHECALLBACK::arg, elog, FATAL, SYSCACHECALLBACK::function, SYSCACHECALLBACK::id, MAX_SYSCACHE_CALLBACKS, syscache_callback_count, and syscache_callback_list.
Referenced by BuildEventTriggerCache(), find_oper_cache_entry(), get_btree_test_op(), init_ts_config_cache(), initialize_acl(), InitializeAttoptCache(), InitializeSearchPath(), InitializeTableSpaceCache(), InitPlanCache(), lookup_ts_dictionary_cache(), lookup_ts_parser_cache(), ri_InitHashTables(), and superuser_arg().
{ if (syscache_callback_count >= MAX_SYSCACHE_CALLBACKS) elog(FATAL, "out of syscache_callback_list slots"); syscache_callback_list[syscache_callback_count].id = cacheid; syscache_callback_list[syscache_callback_count].function = func; syscache_callback_list[syscache_callback_count].arg = arg; ++syscache_callback_count; }
void CallSyscacheCallbacks | ( | int | cacheid, | |
uint32 | hashvalue | |||
) |
Definition at line 1276 of file inval.c.
References SYSCACHECALLBACK::arg, SYSCACHECALLBACK::function, i, SYSCACHECALLBACK::id, syscache_callback_count, and syscache_callback_list.
Referenced by CatalogCacheFlushCatalog(), and LocalExecuteInvalidationMessage().
{ int i; for (i = 0; i < syscache_callback_count; i++) { struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i; if (ccitem->id == cacheid) (*ccitem->function) (ccitem->arg, cacheid, hashvalue); } }
void CommandEndInvalidationMessages | ( | void | ) |
Definition at line 950 of file inval.c.
References AppendInvalidationMessages(), TransInvalidationInfo::CurrentCmdInvalidMsgs, LocalExecuteInvalidationMessage(), NULL, TransInvalidationInfo::PriorCmdInvalidMsgs, and ProcessInvalidationMessages().
Referenced by AtCCI_LocalCache(), and AtEOSubXact_Inval().
{ /* * You might think this shouldn't be called outside any transaction, but * bootstrap does it, and also ABORT issued when not in a transaction. So * just quietly return if no state to work on. */ if (transInvalInfo == NULL) return; ProcessInvalidationMessages(&transInvalInfo->CurrentCmdInvalidMsgs, LocalExecuteInvalidationMessage); AppendInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs, &transInvalInfo->CurrentCmdInvalidMsgs); }
static void InvalidateSystemCaches | ( | void | ) | [static] |
Definition at line 551 of file inval.c.
References RELCACHECALLBACK::arg, SYSCACHECALLBACK::arg, RELCACHECALLBACK::function, SYSCACHECALLBACK::function, i, SYSCACHECALLBACK::id, InvalidOid, RelationCacheInvalidate(), relcache_callback_count, relcache_callback_list, ResetCatalogCaches(), syscache_callback_count, and syscache_callback_list.
Referenced by AcceptInvalidationMessages().
{ int i; ResetCatalogCaches(); RelationCacheInvalidate(); /* gets smgr and relmap too */ for (i = 0; i < syscache_callback_count; i++) { struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i; (*ccitem->function) (ccitem->arg, ccitem->id, 0); } for (i = 0; i < relcache_callback_count; i++) { struct RELCACHECALLBACK *ccitem = relcache_callback_list + i; (*ccitem->function) (ccitem->arg, InvalidOid); } }
static void LocalExecuteInvalidationMessage | ( | SharedInvalidationMessage * | msg | ) | [static] |
Definition at line 479 of file inval.c.
References RELCACHECALLBACK::arg, RelFileNodeBackend::backend, SharedInvalSmgrMsg::backend_hi, SharedInvalSmgrMsg::backend_lo, CallSyscacheCallbacks(), SharedInvalidationMessage::cat, CatalogCacheFlushCatalog(), CatalogCacheIdInvalidate(), SharedInvalCatalogMsg::catId, SharedInvalidationMessage::cc, SharedInvalRelmapMsg::dbId, SharedInvalRelcacheMsg::dbId, SharedInvalCatalogMsg::dbId, SharedInvalCatcacheMsg::dbId, elog, FATAL, RELCACHECALLBACK::function, SharedInvalCatcacheMsg::hashValue, i, SharedInvalCatcacheMsg::id, SharedInvalidationMessage::id, InvalidOid, MyDatabaseId, RelFileNodeBackend::node, SharedInvalidationMessage::rc, RelationCacheInvalidateEntry(), RelationMapInvalidate(), relcache_callback_count, relcache_callback_list, SharedInvalRelcacheMsg::relId, SharedInvalidationMessage::rm, SharedInvalSmgrMsg::rnode, SHAREDINVALCATALOG_ID, SHAREDINVALRELCACHE_ID, SHAREDINVALRELMAP_ID, SHAREDINVALSMGR_ID, SharedInvalidationMessage::sm, and smgrclosenode().
Referenced by AcceptInvalidationMessages(), AtEOSubXact_Inval(), AtEOXact_Inval(), and CommandEndInvalidationMessages().
{ if (msg->id >= 0) { if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == InvalidOid) { CatalogCacheIdInvalidate(msg->cc.id, msg->cc.hashValue); CallSyscacheCallbacks(msg->cc.id, msg->cc.hashValue); } } else if (msg->id == SHAREDINVALCATALOG_ID) { if (msg->cat.dbId == MyDatabaseId || msg->cat.dbId == InvalidOid) { CatalogCacheFlushCatalog(msg->cat.catId); /* CatalogCacheFlushCatalog calls CallSyscacheCallbacks as needed */ } } else if (msg->id == SHAREDINVALRELCACHE_ID) { if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == InvalidOid) { int i; RelationCacheInvalidateEntry(msg->rc.relId); for (i = 0; i < relcache_callback_count; i++) { struct RELCACHECALLBACK *ccitem = relcache_callback_list + i; (*ccitem->function) (ccitem->arg, msg->rc.relId); } } } else if (msg->id == SHAREDINVALSMGR_ID) { /* * We could have smgr entries for relations of other databases, so no * short-circuit test is possible here. */ RelFileNodeBackend rnode; rnode.node = msg->sm.rnode; rnode.backend = (msg->sm.backend_hi << 16) | (int) msg->sm.backend_lo; smgrclosenode(rnode); } else if (msg->id == SHAREDINVALRELMAP_ID) { /* We only care about our own database and shared catalogs */ if (msg->rm.dbId == InvalidOid) RelationMapInvalidate(true); else if (msg->rm.dbId == MyDatabaseId) RelationMapInvalidate(false); } else elog(FATAL, "unrecognized SI message ID: %d", msg->id); }
static void MakeSharedInvalidMessagesArray | ( | const SharedInvalidationMessage * | msgs, | |
int | n | |||
) | [static] |
Definition at line 680 of file inval.c.
References maxSharedInvalidMessagesArray, NULL, numSharedInvalidMessagesArray, palloc(), and repalloc().
Referenced by xactGetCommittedInvalidationMessages().
{ /* * Initialise array first time through in each commit */ if (SharedInvalidMessagesArray == NULL) { maxSharedInvalidMessagesArray = FIRSTCHUNKSIZE; numSharedInvalidMessagesArray = 0; /* * Although this is being palloc'd we don't actually free it directly. * We're so close to EOXact that we now we're going to lose it anyhow. */ SharedInvalidMessagesArray = palloc(maxSharedInvalidMessagesArray * sizeof(SharedInvalidationMessage)); } if ((numSharedInvalidMessagesArray + n) > maxSharedInvalidMessagesArray) { while ((numSharedInvalidMessagesArray + n) > maxSharedInvalidMessagesArray) maxSharedInvalidMessagesArray *= 2; SharedInvalidMessagesArray = repalloc(SharedInvalidMessagesArray, maxSharedInvalidMessagesArray * sizeof(SharedInvalidationMessage)); } /* * Append the next chunk onto the array */ memcpy(SharedInvalidMessagesArray + numSharedInvalidMessagesArray, msgs, n * sizeof(SharedInvalidationMessage)); numSharedInvalidMessagesArray += n; }
void PostPrepare_Inval | ( | void | ) |
Definition at line 653 of file inval.c.
References AtEOXact_Inval().
Referenced by PrepareTransaction().
{ AtEOXact_Inval(false); }
void ProcessCommittedInvalidationMessages | ( | SharedInvalidationMessage * | msgs, | |
int | nmsgs, | |||
bool | RelcacheInitFileInval, | |||
Oid | dbid, | |||
Oid | tsid | |||
) |
Definition at line 777 of file inval.c.
References DatabasePath, DEBUG4, elog, GetDatabasePath(), pfree(), RelationCacheInitFilePostInvalidate(), RelationCacheInitFilePreInvalidate(), SendSharedInvalidMessages(), and trace_recovery().
Referenced by xact_redo_commit_internal().
{ if (nmsgs <= 0) return; elog(trace_recovery(DEBUG4), "replaying commit with %d messages%s", nmsgs, (RelcacheInitFileInval ? " and relcache file invalidation" : "")); if (RelcacheInitFileInval) { /* * RelationCacheInitFilePreInvalidate requires DatabasePath to be set, * but we should not use SetDatabasePath during recovery, since it is * intended to be used only once by normal backends. Hence, a quick * hack: set DatabasePath directly then unset after use. */ DatabasePath = GetDatabasePath(dbid, tsid); elog(trace_recovery(DEBUG4), "removing relcache init file in \"%s\"", DatabasePath); RelationCacheInitFilePreInvalidate(); pfree(DatabasePath); DatabasePath = NULL; } SendSharedInvalidMessages(msgs, nmsgs); if (RelcacheInitFileInval) RelationCacheInitFilePostInvalidate(); }
static void ProcessInvalidationMessages | ( | InvalidationListHeader * | hdr, | |
void(*)(SharedInvalidationMessage *msg) | func | |||
) | [static] |
Definition at line 394 of file inval.c.
References InvalidationListHeader::cclist, ProcessMessageList, and InvalidationListHeader::rclist.
Referenced by AtEOSubXact_Inval(), AtEOXact_Inval(), and CommandEndInvalidationMessages().
{ ProcessMessageList(hdr->cclist, func(msg)); ProcessMessageList(hdr->rclist, func(msg)); }
static void ProcessInvalidationMessagesMulti | ( | InvalidationListHeader * | hdr, | |
void(*)(const SharedInvalidationMessage *msgs, int n) | func | |||
) | [static] |
Definition at line 406 of file inval.c.
References InvalidationListHeader::cclist, ProcessMessageListMulti, and InvalidationListHeader::rclist.
Referenced by AtEOXact_Inval(), and xactGetCommittedInvalidationMessages().
{ ProcessMessageListMulti(hdr->cclist, func(msgs, n)); ProcessMessageListMulti(hdr->rclist, func(msgs, n)); }
Definition at line 438 of file inval.c.
References AddCatalogInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.
Referenced by CacheInvalidateCatalog().
{ AddCatalogInvalidationMessage(&transInvalInfo->CurrentCmdInvalidMsgs, dbId, catId); }
Definition at line 424 of file inval.c.
References AddCatcacheInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.
Referenced by CacheInvalidateHeapTuple().
{ AddCatcacheInvalidationMessage(&transInvalInfo->CurrentCmdInvalidMsgs, cacheId, hashValue, dbId); }
Definition at line 450 of file inval.c.
References AddRelcacheInvalidationMessage(), TransInvalidationInfo::CurrentCmdInvalidMsgs, GetCurrentCommandId(), RelationIdIsInInitFile(), and TransInvalidationInfo::RelcacheInitFileInval.
Referenced by CacheInvalidateHeapTuple(), CacheInvalidateRelcache(), and CacheInvalidateRelcacheByTuple().
{ AddRelcacheInvalidationMessage(&transInvalInfo->CurrentCmdInvalidMsgs, dbId, relId); /* * Most of the time, relcache invalidation is associated with system * catalog updates, but there are a few cases where it isn't. Quick hack * to ensure that the next CommandCounterIncrement() will think that we * need to do CommandEndInvalidationMessages(). */ (void) GetCurrentCommandId(true); /* * If the relation being invalidated is one of those cached in the * relcache init file, mark that we need to zap that file at commit. */ if (RelationIdIsInInitFile(relId)) transInvalInfo->RelcacheInitFileInval = true; }
int xactGetCommittedInvalidationMessages | ( | SharedInvalidationMessage ** | msgs, | |
bool * | RelcacheInitFileInval | |||
) |
Definition at line 730 of file inval.c.
References Assert, TransInvalidationInfo::CurrentCmdInvalidMsgs, CurTransactionContext, MakeSharedInvalidMessagesArray(), MemoryContextSwitchTo(), NULL, numSharedInvalidMessagesArray, TransInvalidationInfo::parent, TransInvalidationInfo::PriorCmdInvalidMsgs, ProcessInvalidationMessagesMulti(), and TransInvalidationInfo::RelcacheInitFileInval.
Referenced by RecordTransactionCommit(), and StartPrepare().
{ MemoryContext oldcontext; /* Must be at top of stack */ Assert(transInvalInfo != NULL && transInvalInfo->parent == NULL); /* * Relcache init file invalidation requires processing both before and * after we send the SI messages. However, we need not do anything unless * we committed. */ *RelcacheInitFileInval = transInvalInfo->RelcacheInitFileInval; /* * Walk through TransInvalidationInfo to collect all the messages into a * single contiguous array of invalidation messages. It must be contiguous * so we can copy directly into WAL message. Maintain the order that they * would be processed in by AtEOXact_Inval(), to ensure emulated behaviour * in redo is as similar as possible to original. We want the same bugs, * if any, not new ones. */ oldcontext = MemoryContextSwitchTo(CurTransactionContext); ProcessInvalidationMessagesMulti(&transInvalInfo->CurrentCmdInvalidMsgs, MakeSharedInvalidMessagesArray); ProcessInvalidationMessagesMulti(&transInvalInfo->PriorCmdInvalidMsgs, MakeSharedInvalidMessagesArray); MemoryContextSwitchTo(oldcontext); Assert(!(numSharedInvalidMessagesArray > 0 && SharedInvalidMessagesArray == NULL)); *msgs = SharedInvalidMessagesArray; return numSharedInvalidMessagesArray; }
int maxSharedInvalidMessagesArray [static] |
Definition at line 171 of file inval.c.
Referenced by MakeSharedInvalidMessagesArray().
int numSharedInvalidMessagesArray [static] |
Definition at line 170 of file inval.c.
Referenced by AtStart_Inval(), MakeSharedInvalidMessagesArray(), and xactGetCommittedInvalidationMessages().
int relcache_callback_count = 0 [static] |
Definition at line 197 of file inval.c.
Referenced by CacheRegisterRelcacheCallback(), InvalidateSystemCaches(), and LocalExecuteInvalidationMessage().
struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS] [static] |
Referenced by CacheRegisterRelcacheCallback(), InvalidateSystemCaches(), and LocalExecuteInvalidationMessage().
int syscache_callback_count = 0 [static] |
Definition at line 189 of file inval.c.
Referenced by CacheRegisterSyscacheCallback(), CallSyscacheCallbacks(), and InvalidateSystemCaches().
struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS] [static] |
Referenced by CacheRegisterSyscacheCallback(), CallSyscacheCallbacks(), and InvalidateSystemCaches().
TransInvalidationInfo* transInvalInfo = NULL [static] |