PostgreSQL事务初始化过程概要

事务状态结构定义如下:

typedef struct TransactionStateData
{
	TransactionId transactionId;	/* my XID, or Invalid if none */
	SubTransactionId subTransactionId;	/* my subxact ID */
	char	   *name;			/* savepoint name, if any */
	int			savepointLevel; /* savepoint level */
	TransState	state;			/* low-level state */
	TBlockState blockState;		/* high-level state */
	int			nestingLevel;	/* transaction nesting depth */
	int			gucNestLevel;	/* GUC context nesting depth */
	MemoryContext curTransactionContext;		/* my xact-lifetime context */
	ResourceOwner curTransactionOwner;	/* my query resources */
	TransactionId *childXids;	/* subcommitted child XIDs, in XID order */
	int			nChildXids;		/* # of subcommitted child XIDs */
	int			maxChildXids;	/* allocated size of childXids[] */
	Oid			prevUser;		/* previous CurrentUserId setting */
	int			prevSecContext; /* previous SecurityRestrictionContext */
	bool		prevXactReadOnly;		/* entry-time xact r/o state */
	bool		startedInRecovery;		/* did we start in recovery? */
	bool		didLogXid;		/* has xid been included in WAL record? */
	struct TransactionStateData *parent;		/* back link to parent */
} TransactionStateData;

typedef TransactionStateData *TransactionState;



顶层事务状态初始定义,当前事务状态经常在运行过程中指向它:

static TransactionStateData TopTransactionStateData = {
	0,							/* transaction id */
	0,							/* subtransaction id */
	NULL,						/* savepoint name */
	0,							/* savepoint level */
	TRANS_DEFAULT,				/* transaction state */
	TBLOCK_DEFAULT,				/* transaction block state from the client
								 * perspective */
	0,							/* transaction nesting depth */
	0,							/* GUC context nesting depth */
	NULL,						/* cur transaction context */
	NULL,						/* cur transaction resource owner */
	NULL,						/* subcommitted child Xids */
	0,							/* # of subcommitted child Xids */
	0,							/* allocated size of childXids[] */
	InvalidOid,					/* previous CurrentUserId setting */
	0,							/* previous SecurityRestrictionContext */
	false,						/* entry-time xact r/o state */
	false,						/* startedInRecovery */
	false,						/* didLogXid */
	NULL						/* link to parent state block */
};

当任何语句(或语句块)执行前,都会检查当前事务状态,如果未开始事务,则新开始一个。可以在 src/backend/tcop/postgres.c 函数 exec_simple_query() 中看到相关代码循环体:

...
start_xact_command();
...
for (parsetree_item, parsetree_list) 
...
    start_xact_command();
...

start_xact_command() 函数内:

此处判断事务状态并开始,会用到上述结构定义,并且可以看到使用的状态是 blockState 此时为 TBLOCK_DEFAULT。随后的 StartTransaction() 函数中 state(low-level state) 由 TRANS_DEFAULT 变为 TRANS_START,事务ID 为无效(InvalidTransactionId,也就是0)。

StartTransaction()中也可以看到 PG此时开始了一个虚事务(virtual transaction),并分配了一个本地事务ID。最终经过一系列初始化之后,state 变为 TRANS_INPROGRESS。

成功调用 StartTransaction() 之后 blockState 变为 TBLOCK_STARTED。





你可能感兴趣的:(PostgreSQL事务初始化过程概要)