| 作者 | 时间 | QQ技术交流群 |
| perrynzhou@gmail.com | 2024/04/14 | 672152841 |

介绍
•
postgres
事务系统分为事务块(上层系统)和事务(底层系统)两个部分,上层的事务块提供统一的事务抽象,事务底层系统负责执行具体的底层事务的功能• 在
postgres
中执行如下四个语句,这个语句中BEGIN
和COMMIT
是属于事务块的开始和结束状态;其中的(2)和(3)
是底层事务系统负责具体的执行。
(1) BEGIN
(2) SELECT * FROM foo
(3) INSERT INTO foo VALUES (...)
(4) COMMIT
• 以上的语句都对应
postgres
中的事务系统的处理函数。
/ StartTransactionCommand;
/ StartTransaction;
1) < ProcessUtility; << BEGIN
\ BeginTransactionBlock;
\ CommitTransactionCommand;
/ StartTransactionCommand;
2) / PortalRunSelect; << SELECT ...
\ CommitTransactionCommand;
\ CommandCounterIncrement;
/ StartTransactionCommand;
3) / ProcessQuery; << INSERT ...
\ CommitTransactionCommand;
\ CommandCounterIncrement;
/ StartTransactionCommand;
/ ProcessUtility; << COMMIT
4) < EndTransactionBlock;
\ CommitTransactionCommand;
\ CommitTransaction;
• 上层的事务块系统中,每个事务块都有都有对应的状态,具体定义如下
// 事务块的状态
typedef enum TBlockState
{
// 事务块默认状态
TBLOCK_DEFAULT,
// 执行简单的语句的事务块状态
TBLOCK_STARTED,
// 事务块遇到begin命令设置的状态
TBLOCK_BEGIN,
// 事务块正在处理状态
TBLOCK_INPROGRESS,
// 隐世begin开启事务块处理的状态
TBLOCK_IMPLICIT_INPROGRESS,
TBLOCK_PARALLEL_INPROGRESS,
// 事务块遇到commit/end的时候设置的事务块状态
TBLOCK_END,
// 事务块出错等待rollback
TBLOCK_ABORT,
// 事务块出错以接受到rollback
TBLOCK_ABORT_END,
// 事务块处理中接受到rollback
TBLOCK_ABORT_PENDING,
TBLOCK_PREPARE,
/* subtransaction states */
// 事务块中子事务块状态
TBLOCK_SUBBEGIN, /* starting a subtransaction */
TBLOCK_SUBINPROGRESS, /* live subtransaction */
TBLOCK_SUBRELEASE, /* RELEASE received */
TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
} TBlockState;
• 事务块对应的处理函数,从事务块启动、事务块提交、事务块终止三个方面定义了处理函数
// 开启事务的统一入口
void StartTransactionCommand(void)
// 事务提交的统一入口函数
void CommitTransactionCommand(void)
// 事务终止函数
void AbortCurrentTransaction(void)
• 对于底层的事务系统在
postgres
中定义6种底层事务状态
// 底层事务的状态
typedef enum TransState
{
// 事务默认状态
TRANS_DEFAULT,
// 事务开启
TRANS_START,
// 事务正在处理状态
TRANS_INPROGRESS,
// 事务提交状态
TRANS_COMMIT,
// 事务终止状态
TRANS_ABORT,
// 事务准备状态
TRANS_PREPARE
} TransState;
postgres
接受请求的整体流程
// postgres的服务端主进程代码,监听来自客户端的fd
static int ServerLoop(void)
{
for (;;)
{
// 基于select的模型检查fd
for (int i = 0; i < nevents; i++)
{
// 判断event是否有新的连接
if (events[i].events & WL_SOCKET_ACCEPT)
{
Port *port;
port = ConnCreate(events[i].fd);
if (port)
{
// 创建和启动启动子进程
BackendStartup(port)
{
pid = fork_process();
if(pid == 0){ /* child */
// 运行新的子进程
BackendRun(port)
{
// postgres的进程代码,对于没客户端这是子进程的逻辑
PostgresMain(port->database_name, port->user_name)
{
for (;;)
{
// 读取客户端请求,根据请求命令执行不同的操作
firstchar = ReadCommand(&input_message);
switch (firstchar)
{
case 'Q': /* simple query */
{
// 执行简单的SQL语句
exec_simple_query(query_string);
}
}
}
}
}
}
}
}
}
}
select
执行流程
• 简单的SQL语句中会在事务块内进行SQL语句的执行,整体的流入是事务开启->SQL语句从客户端获取->SQL语句解析->SQL语句重写->生成SQL执行计划->SQL语句执行->事务结束

static void exec_simple_query(const char *query_string)
{
// 开启事务块
start_xact_command()
{
// 具体实现函数
StartTransactionCommand();
}
// 解析SQL语句
parsetree_list = pg_parse_query(query_string);
// 重写SQL语句
querytree_list = pg_analyze_and_rewrite_fixedparams(parsetree, query_string,...);
// 生成执行计划
plantree_list = pg_plan_queries(querytree_list, query_string,...);
// 执行SQL语句
(void) PortalRun(portal,...)
{
// 执行SQL语句
nprocessed = PortalRunSelect(portal, true, count, dest)
{
// 根据执行计划执行SQL语句
ExecutorRun(queryDesc, direction, (uint64) count,...)
{
// 执行SQL语句
standard_ExecutorRun(queryDesc, direction,...)
{
// 根据SQL执行计划获取数据
ExecutePlan(estate,...)
{
for (;;)
{
slot = ExecProcNode(planstate)
{
// 拿nest loop方式扫表方式,这里定义的就是ExecNestLoop
node->ExecProcNode(node)
}
}
}
}
}
}
}
// 事务块结束
finish_xact_command()
{
CommitTransactionCommand();
}
}
文章转载自存储内核技术交流,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




