⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inval.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
PostPrepare_Inval(void){	AtEOXact_Inval(false);}/* * AtSubStart_Inval *		Initialize inval lists at start of a subtransaction. */voidAtSubStart_Inval(void){	TransInvalidationInfo *myInfo;	Assert(transInvalInfo != NULL);	myInfo = (TransInvalidationInfo *)		MemoryContextAllocZero(TopTransactionContext,							   sizeof(TransInvalidationInfo));	myInfo->parent = transInvalInfo;	myInfo->my_level = GetCurrentTransactionNestLevel();	transInvalInfo = myInfo;}/* * PersistInvalidationMessage *		Write an invalidation message to the 2PC state file. */static voidPersistInvalidationMessage(SharedInvalidationMessage *msg){	RegisterTwoPhaseRecord(TWOPHASE_RM_INVAL_ID, TWOPHASE_INFO_MSG,						   msg, sizeof(SharedInvalidationMessage));}/* * inval_twophase_postcommit *		Process an invalidation message from the 2PC state file. */voidinval_twophase_postcommit(TransactionId xid, uint16 info,						  void *recdata, uint32 len){	SharedInvalidationMessage *msg;	switch (info)	{		case TWOPHASE_INFO_MSG:			msg = (SharedInvalidationMessage *) recdata;			Assert(len == sizeof(SharedInvalidationMessage));			SendSharedInvalidMessage(msg);			break;		case TWOPHASE_INFO_FILE_BEFORE:			RelationCacheInitFileInvalidate(true);			break;		case TWOPHASE_INFO_FILE_AFTER:			RelationCacheInitFileInvalidate(false);			break;		default:			Assert(false);			break;	}}/* * AtEOXact_Inval *		Process queued-up invalidation messages at end of main transaction. * * If isCommit, we must send out the messages in our PriorCmdInvalidMsgs list * to the shared invalidation message queue.  Note that these will be read * not only by other backends, but also by our own backend at the next * transaction start (via AcceptInvalidationMessages).	This means that * we can skip immediate local processing of anything that's still in * CurrentCmdInvalidMsgs, and just send that list out too. * * If not isCommit, we are aborting, and must locally process the messages * in PriorCmdInvalidMsgs.	No messages need be sent to other backends, * since they'll not have seen our changed tuples anyway.  We can forget * about CurrentCmdInvalidMsgs too, since those changes haven't touched * the caches yet. * * In any case, reset the various lists to empty.  We need not physically * free memory here, since TopTransactionContext is about to be emptied * anyway. * * Note: *		This should be called as the last step in processing a transaction. */voidAtEOXact_Inval(bool isCommit){	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)			RelationCacheInitFileInvalidate(true);		AppendInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs,								   &transInvalInfo->CurrentCmdInvalidMsgs);		ProcessInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs,									SendSharedInvalidMessage);		if (transInvalInfo->RelcacheInitFileInval)			RelationCacheInitFileInvalidate(false);	}	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;}/* * AtEOSubXact_Inval *		Process queued-up invalidation messages at end of subtransaction. * * If isCommit, process CurrentCmdInvalidMsgs if any (there probably aren't), * and then attach both CurrentCmdInvalidMsgs and PriorCmdInvalidMsgs to the * parent's PriorCmdInvalidMsgs list. * * If not isCommit, we are aborting, and must locally process the messages * in PriorCmdInvalidMsgs.	No messages need be sent to other backends. * We can forget about CurrentCmdInvalidMsgs too, since those changes haven't * touched the caches yet. * * In any case, pop the transaction stack.	We need not physically free memory * here, since CurTransactionContext is about to be emptied anyway * (if aborting).  Beware of the possibility of aborting the same nesting * level twice, though. */voidAtEOSubXact_Inval(bool isCommit){	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);	}}/* * CommandEndInvalidationMessages *		Process queued-up invalidation messages at end of one command *		in a transaction. * * Here, we send no messages to the shared queue, since we don't know yet if * we will commit.	We do need to locally process the CurrentCmdInvalidMsgs * list, so as to flush our caches of any entries we have outdated in the * current command.  We then move the current-cmd list over to become part * of the prior-cmds list. * * Note: *		This should be called during CommandCounterIncrement(), *		after we have advanced the command ID. */voidCommandEndInvalidationMessages(void){	/*	 * 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);}/* * CacheInvalidateHeapTuple *		Register the given tuple for invalidation at end of command *		(ie, current command is creating or outdating this tuple). */voidCacheInvalidateHeapTuple(Relation relation, HeapTuple tuple){	PrepareForTupleInvalidation(relation, tuple);}/* * CacheInvalidateRelcache *		Register invalidation of the specified relation's relcache entry *		at end of command. * * This is used in places that need to force relcache rebuild but aren't * changing any of the tuples recognized as contributors to the relcache * entry by PrepareForTupleInvalidation.  (An example is dropping an index.) * We assume in particular that relfilenode/reltablespace aren't changing * (so the rd_node value is still good). * * XXX most callers of this probably don't need to force an smgr flush. */voidCacheInvalidateRelcache(Relation relation){	Oid			databaseId;	Oid			relationId;	relationId = RelationGetRelid(relation);	if (relation->rd_rel->relisshared)		databaseId = InvalidOid;	else		databaseId = MyDatabaseId;	RegisterRelcacheInvalidation(databaseId, relationId);	RegisterSmgrInvalidation(relation->rd_node);}/* * CacheInvalidateRelcacheByTuple *		As above, but relation is identified by passing its pg_class tuple. */voidCacheInvalidateRelcacheByTuple(HeapTuple classTuple){	Form_pg_class classtup = (Form_pg_class) GETSTRUCT(classTuple);	Oid			databaseId;	Oid			relationId;	RelFileNode rnode;	relationId = HeapTupleGetOid(classTuple);	if (classtup->relisshared)		databaseId = InvalidOid;	else		databaseId = MyDatabaseId;	if (classtup->reltablespace)		rnode.spcNode = classtup->reltablespace;	else		rnode.spcNode = MyDatabaseTableSpace;	rnode.dbNode = databaseId;	rnode.relNode = classtup->relfilenode;	RegisterRelcacheInvalidation(databaseId, relationId);	RegisterSmgrInvalidation(rnode);}/* * CacheInvalidateRelcacheByRelid *		As above, but relation is identified by passing its OID. *		This is the least efficient of the three options; use one of *		the above routines if you have a Relation or pg_class tuple. */voidCacheInvalidateRelcacheByRelid(Oid relid){	HeapTuple	tup;	tup = SearchSysCache(RELOID,						 ObjectIdGetDatum(relid),						 0, 0, 0);	if (!HeapTupleIsValid(tup))		elog(ERROR, "cache lookup failed for relation %u", relid);	CacheInvalidateRelcacheByTuple(tup);	ReleaseSysCache(tup);}/* * CacheRegisterSyscacheCallback *		Register the specified function to be called for all future *		invalidation events in the specified cache. * * NOTE: currently, the OID argument to the callback routine is not * provided for syscache callbacks; the routine doesn't really get any * useful info as to exactly what changed.	It should treat every call * as a "cache flush" request. */voidCacheRegisterSyscacheCallback(int cacheid,							  CacheCallbackFunction func,							  Datum arg){	if (cache_callback_count >= MAX_CACHE_CALLBACKS)		elog(FATAL, "out of cache_callback_list slots");	cache_callback_list[cache_callback_count].id = cacheid;	cache_callback_list[cache_callback_count].function = func;	cache_callback_list[cache_callback_count].arg = arg;	++cache_callback_count;}/* * CacheRegisterRelcacheCallback *		Register the specified function to be called for all future *		relcache invalidation events.  The OID of the relation being *		invalidated will be passed to the function. * * NOTE: InvalidOid will be passed if a cache reset request is received. * In this case the called routines should flush all cached state. */voidCacheRegisterRelcacheCallback(CacheCallbackFunction func,							  Datum arg){	if (cache_callback_count >= MAX_CACHE_CALLBACKS)		elog(FATAL, "out of cache_callback_list slots");	cache_callback_list[cache_callback_count].id = SHAREDINVALRELCACHE_ID;	cache_callback_list[cache_callback_count].function = func;	cache_callback_list[cache_callback_count].arg = arg;	++cache_callback_count;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -