`

PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询一:开启事务

阅读更多

 

在《 PostgreSQL 服务过程中的那些事二: pg 服务进程处理简单查询概览 》里话说以下面的例子对简单查询分支进行讨论,并给出了简单查询方法调用序列,下面就从这儿开始,先回顾一下上节点内容。

进入简单查询分支处理方法 exec_simple_query 后的处理基本上涵盖了《数据库系统实现》这本书里的内容。处理量相当大,先根据流程图概览一下处理过程。为了减小图的大小,把 PostgresMain 以前的调用流程略了。在以后讨论简单查询时 PostgresMain 以前的调用流程也省略了,要回顾可参见《 PostgreSQL 服务过程中的那些事二: pg 服务进程处理简单查询概览 》里的“ Postgres 服务进程处理请求的无限循环调用序列图”。



处理简单查询方法 exec_simple_query 调用序列图

主要的处理过程是先调用 start_xact_command 方法 开启一个事务,再用 pg_parse_query 方法 用词法语法解析工具把查询命令解析为解析树 parsetree ,根据需要调用 PushActiveSnapshot 方法搞一个快照,调用 pg_analyze_and_rewrite 方法分析、根据规则重写解析树为查询树 querytree ,调用 pg_plan_queries 方法把查询树转换到执行计划树 plantree ,在调用相应方法创建 portal 和在 postal 中执行执行计划树并给客户端发回结果。然后退出当前事务,清理内存。

 

1

现在描述这个例子: 数据库 TEST 里有表 TEST1 TEST2 ,现在客户端发出查询“ select cname, comp from test1, test2 where test1.id=test2.id; ”。建表的语句在下面。

create table test1 (ID numeric(10), cname varchar(30));

create table test2 (ID numeric(10), comp varchar(30));

postgres 服务进程分析了查询指令后走了简查查询分支 exec_simple_query

 

         再看一下 exec_simple_query 方法的简化流程图



exec_simple_query 方法的简化流程图

   

2

进了 excu_simple_query 分支的第一件事就是开启一个事务命令, pg 里所有查询都要在事务里进行。下面是开启事务的调用序列图。



Postgres 服务进程简查之开始事务调用序列图

 

         上图大红色方框中显示了启动事物的相关的相关处理,进入 StartTransaction 方法后,使 TransactionStateData * 类型静态全局变量 CurrentTransactionState 指向 TransactionStateData 类型静态全局变量 TopTransactionStateData ,在 CurrentTransactionState 设置当前事务状态,记录当前事务 ID 和当前命令 ID 。然后调用 AtStart_Memory 方法 创建内存上下文 "TransactionAbortContext" "TopTransactionContext" ,接着调用 AtStart_ResourceOwner 方法在内存上下文 "TopMemoryContext" 中创建 资源属 ResourceOwnerData 类型变量 curTransationOwner ,并让 CurrentTransactionState ResourceOwnerData* 类型成员 curTransactionOwner 指向该变量。用以上建立的结构 管理该事务涉 及到资源。描述着比较难理清关系,看下面的图吧。



记录事务状态及管理事务资源的相关结构图

    从图中看见事务相关的 资源属 ResourceOwnerData 管理的事务资源包括关系内存缓存、系统表缓存 catcache 、关系模式缓存 relcache 、执行计划缓存 plancache 、查询命令相关元组描述符缓存 tupdesc 、事务相关快照以及打开的临时文件等。

 

事务状态及管理事务资源的相关结构见下面:

 

/*

  *  transaction state structure

  */

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? */

    struct TransactionStateData * parent ;        /* back link to parent */

} TransactionStateData ;

 

typedef TransactionStateData * TransactionState ;

 

/*

  * CurrentTransactionState always points to the current transaction state

  * block.  It will point to TopTransactionStateData when not in a

  * transaction at all, or when in a top-level transaction.

  */

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 */

    NULL                        /* link to parent state block */

};

 

static TransactionState CurrentTransactionState = &TopTransactionStateData;

 

3

         接着调用 VirtualXactLockTableInsert 方法给该事务一个 VirtualTransactionId (这个类型是把 pg 服务进程 ID 和该进程上的事务 ID 关联起来的结构) 类型的虚拟事务 ID VXID ,并加锁。 VirtualTransactionId 的类型定义见下面:

 

typedef struct

{

    BackendId    backendId ;      /* determined at backend startup */

    LocalTransactionId localTransactionId ;      /* backend -local transaction

                                                  * id */

} VirtualTransactionId ;

 

         然后为这个新事物调用下面的方法初始化相关子系统。

在事务开始时调用 AtStart_GUC() 设置事务嵌套层数,调用 AtStart_Inval() 方法初始化管理该事务失效信息用的 TransInvalidationInfo 类型 结构,调用 AtStart_Cache 方法从共享失效消息队列读取并处理失效消息,调用 AfterTriggerBeginXact 方法初始化 AfterTriggersData 类型结构以备后面处理相关 AFTER 的触发器。 AfterTriggersData 的结构定义见下面:

         typedef struct AfterTriggersData

{

    CommandId    firing_counter ; /* next firing ID to assign */

    SetConstraintState state ;   /* the active S C state */

    AfterTriggerEventList events ;       /* deferred-event list */

    int          query_depth ;    /* current query list index */

    AfterTriggerEventList * query_stack ; /* events pending from each query */

    int          maxquerydepth ;  /* allocated len of above array */

    MemoryContext event_cxt ;    /* memory context for events, if any */

 

    /* these fields are just for resetting at subtrans abort: */

 

    SetConstraintState * state_stack ;    /* stacked S C states */

    AfterTriggerEventList * events_stack ;        /* stacked list pointers */

    int         * depth_stack ; /* stacked query_depths */

    CommandId   * firing_stack ;   /* stacked firing_counters */

    int          maxtransdepth ;  /* allocated len of above arrays */

} AfterTriggersData ;

 

StartTransaction 方法里主要干了上面这些事并设置了记录事务状态的结构 CurrentTransactionState 的成员,其中有一个成员 TransState state TransState 是枚举类型,表示事务状态,其定义如下:

/*

  *  transaction states - transaction state from server perspective

  */

typedef enum TransState

{

    TRANS_DEFAULT ,              /* idle */

    TRANS_START ,                /* transaction starting */

    TRANS_INPROGRESS ,           /* inside a valid transaction */

    TRANS_COMMIT ,               /* commit in progress */

    TRANS_ABORT ,                /* abort in progress */

    TRANS_PREPARE                /* prepare in progress */

} TransState ;

 

好了,这节就到这儿。

 



------------
转载请著明出处,来自博客:
blog.csdn.net/beiigang
beigang.iteye.com



  • 大小: 65.3 KB
  • 大小: 120.1 KB
  • 大小: 64.1 KB
  • 大小: 70 KB
1
1
分享到:
评论

相关推荐

    PostgreSQL中文手册9.2

    一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: . 50 PostgreSQL PostgreSQL...

    PostgreSQL技术内幕:事务处理深度探索.docx

    PostgreSQL 的事务处理机制是数据库系统中非常重要的一个环节,它确保了数据的一致性和完整性。 在本文中,我们将深入探讨 PostgreSQL 的事务处理机制,包括事务的基本概念、事务处理的原理、事务处理的优化方案等...

    PostgreSQL 存储过程调试

    在IT行业中,数据库管理系统是核心组件之一,而PostgreSQL作为一款开源、强大的对象关系型数据库系统,被广泛应用于各种业务场景。本篇文章将深入探讨如何对PostgreSQL的存储过程进行调试,这对于优化数据库性能和...

    PGAdmin系统管理PostgreSQL 中文手册

    pgAdmin是一款免费的开源软件,专为PostgreSQL设计,提供了直观的界面,使得数据库的管理、查询、备份以及监控等工作变得简单易行。 **1. pgAdmin简介** pgAdmin是PostgreSQL数据库管理员和开发者的理想选择,它...

    浅析PostgreSQL事务处理机制

    ### 浅析PostgreSQL事务处理机制 #### PostgreSQL简介 PostgreSQL是一款开源的对象关系数据库系统,其历史可以追溯至1977年,由Michael Stonebraker领导的加州伯克利分校的INGRES项目发端。它支持大部分SQL标准,...

    Postgresql存储过程

    Postgresql存储过程是指在Postgresql数据库中定义的一组SQL语句的集合,它可以完成复杂的操作,并且可以重复使用。Postgresql存储过程可以用来实现业务逻辑,减少数据库服务器的压力和网络传输的数据量。 一、存储...

    postgresql查询死锁以及杀死死锁进程sql.txt

    查询sql的死锁进程,查找并杀死。解决生产数据库中卡死的现象。postgresql查询死锁以及杀死死锁进程sql

    DBD-Pg-2.15.1

    在实际应用中,DBD::Pg允许开发者执行SQL查询、事务管理、游标操作、结果集处理等常见的数据库操作。使用DBI和DBD::Pg,开发者可以编写可移植的代码,只需更换数据库驱动,就可以轻松地将应用程序从一种数据库系统...

    dbdpg:Perl Postgres驱动程序DBD :: Pg aka dbdpg

    标题"dbdpg:Perl Postgres驱动程序DBD :: Pg aka dbdpg"提及的是一个Perl编程语言中的数据库驱动模块,DBD::Pg,它专门用于连接和操作PostgreSQL数据库系统。"aka dbdpg"是这个模块的别名,可能在某些场合下被人们...

    Postgresql开启远程访问的步骤全纪录

    总结,开启 PostgreSQL 的远程访问涉及对 `postgresql.conf` 和 `pg_hba.conf` 的修改,以及随后的服务重启。确保遵循最佳安全实践,限制访问权限,并保持数据库软件的最新状态,以确保数据的安全。希望这个指南对你...

    linux搭建postgresql、postgis、pg_pathman环境步骤以及需要的软件包

    在Linux系统上搭建PostgreSQL、PostGIS和pg_pathman环境是一项关键的任务,这些组件共同构成了一个强大的地理空间数据库解决方案。PostgreSQL是一种开源的关系型数据库管理系统,具有高度的可扩展性和可靠性;...

    关于PostGreSQL中的存储过程

    PostgreSQL 存储过程详解 PostgreSQL 是一个开源的数据库管理系统,它提供了强大的数据存储和管理功能。...本文详细介绍了 PostgreSQL 中的存储过程,并提供了一个使用函数来查询数据的示例代码。

    postgresql--内核分析--多进程结构

    ### PostgreSQL内核分析——多进程结构 #### 一、进程的理解与创建 进程是一个正在运行的程序实例,它具有动态的特性。对于程序员而言,所编写的代码在未经编译之前仅是静态的源代码。当这些代码经过编译、链接等...

    pgadmin3 - 1.14.2 Postgresql 客户端程序

    作为PostgreSQL的主要客户端工具之一,它提供了丰富的功能,包括数据库创建、表设计、查询执行、视图管理、索引操作、触发器和存储过程的创建等。此外,pgAdmin3还支持角色管理、备份和恢复、性能监控等高级功能,...

    Go-PostgreSQLBGWorker用Go编写的PostgreSQL后台工作进程

    在PostgreSQL数据库系统中,后台工作进程(Background Worker)是一种扩展其功能的重要机制。这些进程独立于主要的数据库服务器进程运行,允许开发者实现自定义任务,如定期维护、监控或其他后台服务。Go语言以其...

    postgresql-embedded,嵌入式PostgreSQL服务器.zip

    PostgreSQL是一个功能强大的【开源关系型数据库管理系统】,支持SQL标准,并提供了许多高级特性,如事务处理、复杂的查询、多版本并发控制(MVCC)等。其开源属性意味着任何人都可以自由地使用、修改和分发,这极大...

    PostgreSQL教程(十一):服务器配置

    ### 一、服务器进程的启动和关闭 PostgreSQL服务器的管理通常通过`pg_ctl`命令进行,它是对`postgres`命令的封装,提供了更为便捷的使用方式。以下是`pg_ctl`的常用选项: 1. **初始化数据库**: - `pg_ctl init...

    appache_pgadmin4postgresql

    对于那些需要处理大量数据或需要复杂查询的项目,PostgreSQL是一个理想的选择。 PgAdmin4是PostgreSQL的官方管理工具,它允许用户通过Web浏览器进行数据库管理。这个压缩包中的"edb_apachephp.exe"文件可能是用于...

    postgresql客户端pgadmin3-1.8.4

    1. **安装与配置**:pgAdmin3-1.8.4的安装过程相对简单,支持Windows、Linux和macOS等多个操作系统。安装完成后,用户需要配置连接参数,如主机名、端口号、数据库名、用户名和密码,以便连接到PostgreSQL服务器。 ...

    PostgreSQL 14.1 中文手册

    PostgreSQL 14.1 手册 PostgreSQL 全球开发组 翻译:彭煜玮1,PostgreSQL中文社区2文档翻译组

Global site tag (gtag.js) - Google Analytics