这篇文章主要讲解了“postgresql中函数StartTransaction的实现逻辑是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Postgres
这篇文章主要讲解了“postgresql中函数StartTransaction的实现逻辑是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Postgresql中函数StartTransaction的实现逻辑是什么”吧!
静态变量
当前事务状态CurrentTransactionState
static TransactionStateData TopTransactionStateData = {
.state = TRANS_DEFAULT,
.blockState = TBLOCK_DEFAULT,
};
static int nUnreportedXids;
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
static TransactionState CurrentTransactionState = &TopTransactionStateData;
static SubTransactionId currentSubTransactionId;
static CommandId currentCommandId;
static bool currentCommandIdUsed;
TransactionState
事务状态结构体
typedef enum TransState
{
TRANS_DEFAULT,
TRANS_START,
TRANS_INPROGRESS,
TRANS_COMMIT,
TRANS_ABORT,
TRANS_PREPARE
} TransState;
typedef enum TBlockState
{
TBLOCK_DEFAULT,
TBLOCK_STARTED,
TBLOCK_BEGIN,
TBLOCK_INPROGRESS,
TBLOCK_IMPLICIT_INPROGRESS,
TBLOCK_PARALLEL_INPROGRESS,
TBLOCK_END,
TBLOCK_ABORT,
TBLOCK_ABORT_END,
TBLOCK_ABORT_PENDING,
TBLOCK_PREPARE,
TBLOCK_SUBBEGIN,
TBLOCK_SUBINPROGRESS,
TBLOCK_SUBRELEASE,
TBLOCK_SUBCOMMIT,
TBLOCK_SUBABORT,
TBLOCK_SUBABORT_END,
TBLOCK_SUBABORT_PENDING,
TBLOCK_SUBRESTART,
TBLOCK_SUBABORT_RESTART
} TBlockState;
typedef struct TransactionStateData
{
//事务ID
TransactionId transactionId;
//子事务ID
SubTransactionId subTransactionId;
//保存点名称
char *name;
//保存点级别
int savepointLevel;
//低级别的事务状态
TransState state;
//高级别的事务状态
TBlockState blockState;
//事务嵌套深度
int nestingLevel;
//GUC上下文嵌套深度
int gucNestLevel;
//事务生命周期上下文
MemoryContext curTransactionContext;
//查询资源
ResourceOwner curTransactionOwner;
//按XID顺序保存的已提交的子事务ID
TransactionId *childXids;
//childXids数组大小
int nChildXids;
//分配的childXids数组空间
int maxChildXids;
//上一个CurrentUserId
Oid prevUser;
//上一个SecurityRestrictionContext
int prevSecContext;
//上一事务是否只读?
bool prevXactReadOnly;
//是否处于Recovery?
bool startedInRecovery;
//XID是否已保存在WAL Record中?
bool didLogXid;
//Enter/ExitParallelMode计数器
int parallelModeLevel;
//父事务状态
struct TransactionStateData *parent;
} TransactionStateData;
//结构体指针
typedef TransactionStateData *TransactionState;
VirtualTransactionId
VirtualTransactionIDs由执行事务的后台进程BackendId和逻辑分配的LocalTransactionId组成.
typedef struct
{
BackendId backendId;
LocalTransactionId localTransactionId;
} VirtualTransactionId;
StartTransaction函数,用于启动事务,设置事务状态为TRANS_INPROGRESS,CurrentTransactionState->state = TRANS_INPROGRESS.
static void
StartTransaction(void)
{
TransactionState s;//事务状态
VirtualTransactionId vxid;//虚拟事务ID
s = &TopTransactionStateData;
CurrentTransactionState = s;
Assert(XactTopTransactionId == InvalidTransactionId);
//检查当前事务状态
Assert(s->state == TRANS_DEFAULT);
s->state = TRANS_START;
//无效事务ID,待分配
s->transactionId = InvalidTransactionId;
s->nestingLevel = 1;
s->gucNestLevel = 1;
s->childXids = NULL;
s->nChildXids = 0;
s->maxChildXids = 0;
GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
//SecurityRestrictionContext不应在事务外设置
Assert(s->prevSecContext == 0);
if (RecoveryInProgress())
{
//只读状态
s->startedInRecovery = true;
XactReadOnly = true;
}
else
{
s->startedInRecovery = false;
XactReadOnly = DefaultXactReadOnly;
}
XactDeferrable = DefaultXactDeferrable;
XactIsoLevel = DefaultXactIsoLevel;
forceSyncCommit = false;
MyXactFlags = 0;
s->subTransactionId = TopSubTransactionId;
currentSubTransactionId = TopSubTransactionId;
currentCommandId = FirstCommandId;
currentCommandIdUsed = false;
nUnreportedXids = 0;
s->didLogXid = false;
AtStart_Memory();
AtStart_ResourceOwner();
vxid.backendId = MyBackendId;
vxid.localTransactionId = GetNextLocalTransactionId();
VirtualXactLockTableInsert(vxid);
Assert(MyProc->backendId == vxid.backendId);
MyProc->lxid = vxid.localTransactionId;
TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
if (!IsParallelWorker())
{
if (!SPI_inside_nonatomic_context())
xactStartTimestamp = stmtStartTimestamp;
else
xactStartTimestamp = GetCurrentTimestamp();
}
else
Assert(xactStartTimestamp != 0);
pgstat_report_xact_timestamp(xactStartTimestamp);
//标记xactStopTimestamp未设置
xactStopTimestamp = 0;
AtStart_GUC();
AtStart_Cache();
AfterTriggerBeginXact();
s->state = TRANS_INPROGRESS;
ShowTransactionState("StartTransaction");
}
执行begin,触发该函数调用
11:10:36 (xdb@[local]:5432)testdb=# begin;
启动gdb,设置断点
(gdb) b StartTransaction
Breakpoint 4 at 0x54800f: file xact.c, line 1825.
(gdb) c
Continuing.
Breakpoint 4, StartTransaction () at xact.c:1825
1825 s = &TopTransactionStateData;
(gdb)
查看调用栈
(gdb) bt
#0 StartTransaction () at xact.c:1825
#1 0x0000000000548f50 in StartTransactionCommand () at xact.c:2718
#2 0x00000000008c8e7d in start_xact_command () at postgres.c:2500
#3 0x00000000008c6771 in exec_simple_query (query_string=0x24a6ec8 "begin;") at postgres.c:948
#4 0x00000000008cae70 in PostgresMain (arGC=1, argv=0x24d2dc8, dbname=0x24d2c30 "testdb", username=0x24a3ba8 "xdb")
at postgres.c:4182
#5 0x000000000082642b in BackendRun (port=0x24c8c00) at postmaster.c:4361
#6 0x0000000000825b8f in BackendStartup (port=0x24c8c00) at postmaster.c:4033
#7 0x0000000000821f1c in ServerLoop () at postmaster.c:1706
#8 0x00000000008217b4 in PostmasterMain (argc=1, argv=0x24a1b60) at postmaster.c:1379
#9 0x00000000007488ef in main (argc=1, argv=0x24a1b60) at main.c:228
(gdb)
查看TopTransactionStateData全局变量(尚未初始化)
(gdb) p TopTransactionStateData
$7 = {transactionId = 0, subTransactionId = 0, name = 0x0, savepointLevel = 0, state = TRANS_DEFAULT,
blockState = TBLOCK_DEFAULT, nestingLevel = 0, gucNestLevel = 0, curTransactionContext = 0x0, curTransactionOwner = 0x0,
childXids = 0x0, nChildXids = 0, maxChildXids = 0, prevUser = 10, prevSecContext = 0, prevXactReadOnly = false,
startedInRecovery = false, didLogXid = true, parallelModeLevel = 0, parent = 0x0}
设置全局变量CurrentTransactionState = & TopTransactionStateData;
(gdb) n
1826 CurrentTransactionState = s;
(gdb)
1828 Assert(XactTopTransactionId == InvalidTransactionId);
(gdb)
初始化事务状态
(gdb) n
1833 if (s->state != TRANS_DEFAULT)
(gdb)
1841 s->state = TRANS_START;
(gdb)
1842 s->transactionId = InvalidTransactionId;
(gdb)
1852 if (RecoveryInProgress())
(gdb)
1859 s->startedInRecovery = false;
(gdb)
1860 XactReadOnly = DefaultXactReadOnly;
(gdb)
1862 XactDeferrable = DefaultXactDeferrable;
(gdb)
1863 XactIsoLevel = DefaultXactIsoLevel;
(gdb)
1864 forceSyncCommit = false;
(gdb)
1865 MyXactFlags = 0;
(gdb)
1870 s->subTransactionId = TopSubTransactionId;
(gdb)
1871 currentSubTransactionId = TopSubTransactionId;
(gdb)
1872 currentCommandId = FirstCommandId;
(gdb)
1873 currentCommandIdUsed = false;
(gdb)
1878 nUnreportedXids = 0;
(gdb)
1879 s->didLogXid = false;
(gdb)
1884 AtStart_Memory();
(gdb)
启动subsystem(内存/GUC/Cache等)
(gdb)
1884 AtStart_Memory();
(gdb) n
1885 AtStart_ResourceOwner();
(gdb)
设置虚拟事务ID
1891 vxid.backendId = MyBackendId;
(gdb)
1892 vxid.localTransactionId = GetNextLocalTransactionId();
(gdb)
1897 VirtualXactLockTableInsert(vxid);
(gdb)
1903 Assert(MyProc->backendId == vxid.backendId);
(gdb) p vxid
$8 = {backendId = 3, localTransactionId = 6}
(gdb)
(gdb) n
1904 MyProc->lxid = vxid.localTransactionId;
(gdb)
设置时间戳
1906 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
(gdb)
1917 if (!IsParallelWorker())
(gdb)
1919 if (!SPI_inside_nonatomic_context())
(gdb)
1920 xactStartTimestamp = stmtStartTimestamp;
(gdb)
1926 pgstat_report_xact_timestamp(xactStartTimestamp);
(gdb)
1928 xactStopTimestamp = 0;
(gdb)
(gdb) p xactStartTimestamp
$9 = 601009839154257
初始化其他字段
(gdb) n
1935 s->nestingLevel = 1;
(gdb) n
1936 s->gucNestLevel = 1;
(gdb)
1937 s->childXids = NULL;
(gdb)
1938 s->nChildXids = 0;
(gdb)
1939 s->maxChildXids = 0;
(gdb)
1940 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
(gdb)
1942 Assert(s->prevSecContext == 0);
(gdb)
1947 AtStart_GUC();
(gdb)
1948 AtStart_Cache();
(gdb)
1949 AfterTriggerBeginXact();
(gdb)
1955 s->state = TRANS_INPROGRESS;
(gdb)
1957 ShowTransactionState("StartTransaction");
(gdb)
1958 }
(gdb)
初始化后的事务状态
(gdb) p *s
$10 = {transactionId = 0, subTransactionId = 1, name = 0x0, savepointLevel = 0, state = TRANS_INPROGRESS,
blockState = TBLOCK_DEFAULT, nestingLevel = 1, gucNestLevel = 1, curTransactionContext = 0x2523850,
curTransactionOwner = 0x24d4868, childXids = 0x0, nChildXids = 0, maxChildXids = 0, prevUser = 10, prevSecContext = 0,
prevXactReadOnly = false, startedInRecovery = false, didLogXid = false, parallelModeLevel = 0, parent = 0x0}
(gdb)
完成调用
(gdb) n
StartTransactionCommand () at xact.c:2719
2719 s->blockState = TBLOCK_STARTED;
(gdb)
2720 break;
(gdb)
感谢各位的阅读,以上就是“PostgreSQL中函数StartTransaction的实现逻辑是什么”的内容了,经过本文的学习后,相信大家对PostgreSQL中函数StartTransaction的实现逻辑是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!
--结束END--
本文标题: PostgreSQL中函数StartTransaction的实现逻辑是什么
本文链接: https://www.lsjlt.com/news/64851.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-16
2024-05-16
2024-05-16
2024-05-15
2024-05-15
2024-05-15
2024-05-15
2024-05-15
2024-05-15
2024-05-15
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0