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

📄 transam.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * transam.c *	  postgres transaction log/time interface routines * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.27.2.2 1999/08/08 20:24:12 tgl Exp $ * * NOTES *	  This file contains the high level access-method interface to the *	  transaction system. * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/heapam.h"#include "catalog/catname.h"static int	RecoveryCheckingEnabled(void);static void TransRecover(Relation logRelation);static bool TransactionLogTest(TransactionId transactionId, XidStatus status);static void TransactionLogUpdate(TransactionId transactionId,					 XidStatus status);/* ---------------- *	  global variables holding pointers to relations used *	  by the transaction system.  These are initialized by *	  InitializeTransactionLog(). * ---------------- */Relation	LogRelation = (Relation) NULL;Relation	VariableRelation = (Relation) NULL;/* ---------------- *		global variables holding cached transaction id's and statuses. * ---------------- */TransactionId cachedTestXid;XidStatus	cachedTestXidStatus;/* ---------------- *		transaction system constants * ---------------- *//* ---------------------------------------------------------------- *		transaction system constants * *		read the comments for GetNewTransactionId in order to *		understand the initial values for AmiTransactionId and *		FirstTransactionId. -cim 3/23/90 * ---------------------------------------------------------------- */TransactionId NullTransactionId = (TransactionId) 0;TransactionId AmiTransactionId = (TransactionId) 512;TransactionId FirstTransactionId = (TransactionId) 514;/* ---------------- *		transaction recovery state variables * *		When the transaction system is initialized, we may *		need to do recovery checking.  This decision is decided *		by the postmaster or the user by supplying the backend *		with a special flag.  In general, we want to do recovery *		checking whenever we are running without a postmaster *		or when the number of backends running under the postmaster *		goes from zero to one. -cim 3/21/90 * ---------------- */int			RecoveryCheckingEnableState = 0;/* ------------------ *		spinlock for oid generation * ----------------- */extern int	OidGenLockId;/* ---------------- *		recovery checking accessors * ---------------- */static intRecoveryCheckingEnabled(void){	return RecoveryCheckingEnableState;}#ifdef NOT_USEDstatic voidSetRecoveryCheckingEnabled(bool state){	RecoveryCheckingEnableState = (state == true);}#endif/* ---------------------------------------------------------------- *		postgres log access method interface * *		TransactionLogTest *		TransactionLogUpdate *		======== *		   these functions do work for the interface *		   functions - they search/retrieve and append/update *		   information in the log and time relations. * ---------------------------------------------------------------- *//* -------------------------------- *		TransactionLogTest * -------------------------------- */static bool						/* true/false: does transaction id have								 * specified status? */TransactionLogTest(TransactionId transactionId, /* transaction id to test */				   XidStatus status)	/* transaction status */{	BlockNumber blockNumber;	XidStatus	xidstatus;		/* recorded status of xid */	bool		fail = false;	/* success/failure */	/* ----------------	 *	during initialization consider all transactions	 *	as having been committed	 * ----------------	 */	if (!RelationIsValid(LogRelation))		return (bool) (status == XID_COMMIT);	/* ----------------	 *	 before going to the buffer manager, check our single	 *	 item cache to see if we didn't just check the transaction	 *	 status a moment ago.	 * ----------------	 */	if (TransactionIdEquals(transactionId, cachedTestXid))		return (bool)			(status == cachedTestXidStatus);	/* ----------------	 *	compute the item pointer corresponding to the	 *	page containing our transaction id.  We save the item in	 *	our cache to speed up things if we happen to ask for the	 *	same xid's status more than once.	 * ----------------	 */	TransComputeBlockNumber(LogRelation, transactionId, &blockNumber);	xidstatus = TransBlockNumberGetXidStatus(LogRelation,											 blockNumber,											 transactionId,											 &fail);	if (!fail)	{		/*		 * DO NOT cache status for transactions in unknown state !!!		 */		if (xidstatus == XID_COMMIT || xidstatus == XID_ABORT)		{			TransactionIdStore(transactionId, &cachedTestXid);			cachedTestXidStatus = xidstatus;		}		return (bool) (status == xidstatus);	}	/* ----------------	 *	  here the block didn't contain the information we wanted	 * ----------------	 */	elog(ERROR, "TransactionLogTest: failed to get xidstatus");	/*	 * so lint is happy...	 */	return false;}/* -------------------------------- *		TransactionLogUpdate * -------------------------------- */static voidTransactionLogUpdate(TransactionId transactionId,		/* trans id to update */					 XidStatus status)	/* new trans status */{	BlockNumber blockNumber;	bool		fail = false;	/* success/failure */	/* ----------------	 *	during initialization we don't record any updates.	 * ----------------	 */	if (!RelationIsValid(LogRelation))		return;	/* ----------------	 *	update the log relation	 * ----------------	 */	TransComputeBlockNumber(LogRelation, transactionId, &blockNumber);	TransBlockNumberSetXidStatus(LogRelation,								 blockNumber,								 transactionId,								 status,								 &fail);	/*	 * update (invalidate) our single item TransactionLogTest cache.	 *	 * if (status != XID_COMMIT)	 *	 * What's the hell ?! Why != XID_COMMIT ?!	 */	TransactionIdStore(transactionId, &cachedTestXid);	cachedTestXidStatus = status;}/* ---------------------------------------------------------------- *					 transaction recovery code * ---------------------------------------------------------------- *//* -------------------------------- *		TransRecover * *		preform transaction recovery checking. * *		Note: this should only be preformed if no other backends *			  are running.	This is known by the postmaster and *			  conveyed by the postmaster passing a "do recovery checking" *			  flag to the backend. * *		here we get the last recorded transaction from the log, *		get the "last" and "next" transactions from the variable relation *		and then preform some integrity tests: * *		1) No transaction may exist higher then the "next" available *		   transaction recorded in the variable relation.  If this is the *		   case then it means either the log or the variable relation *		   has become corrupted. * *		2) The last committed transaction may not be higher then the *		   next available transaction for the same reason. * *		3) The last recorded transaction may not be lower then the *		   last committed transaction.	(the reverse is ok - it means *		   that some transactions have aborted since the last commit) * *		Here is what the proper situation looks like.  The line *		represents the data stored in the log.	'c' indicates the *		transaction was recorded as committed, 'a' indicates an *		abortted transaction and '.' represents information not *		recorded.  These may correspond to in progress transactions. * *			 c	c  a  c  .	.  a  .  .	.  .  .  .	.  .  .  . *					  |					| *					 last			   next * *		Since "next" is only incremented by GetNewTransactionId() which *		is called when transactions are started.  Hence if there *		are commits or aborts after "next", then it means we committed *		or aborted BEFORE we started the transaction.  This is the *		rational behind constraint (1). * *		Likewise, "last" should never greater then "next" for essentially *		the same reason - it would imply we committed before we started. *		This is the reasoning for (2). * *		(3) implies we may never have a situation such as: * *			 c	c  a  c  .	.  a  c  .	.  .  .  .	.  .  .  . *					  |					| *					 last			   next * *		where there is a 'c' greater then "last".

⌨️ 快捷键说明

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