设为首页 收藏本站
查看: 1013|回复: 0

[经验分享] PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询一:开启事务

[复制链接]

尚未签到

发表于 2016-11-21 07:42:29 | 显示全部楼层 |阅读模式
在《PostgreSQL服务过程中的那些事二:pg服务进程处理简单查询概览》里话说以下面的例子对简单查询分支进行讨论,并给出了简单查询方法调用序列,下面就从这儿开始,先回顾一下上节点内容。

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

DSC0000.png

处理简单查询方法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,现在客户端发出查询“selectcname, comp from test1, test2 where test1.id=test2.id;”。建表的语句在下面。

createtable test1 (ID numeric(10), cname varchar(30));

createtable test2 (ID numeric(10), comp varchar(30));

postgres服务进程分析了查询指令后走了简查查询分支exec_simple_query。
 
         再看一下exec_simple_query方法的简化流程图

DSC0001.png

exec_simple_query方法的简化流程图

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

DSC0002.png

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

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

DSC0003.png

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

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

 

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

 

/*

 *  transactionstate structure

 */

typedef struct TransactionStateData

{

    TransactionId transactionId;    /* my XID, or Invalid if none */

    SubTransactionId subTransactionId/* my subxactID */

    char      *name;           /* savepointname, if any*/

    int         savepointLevel; /* savepointlevel */

    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;   /* subcommittedchild XIDs, in XID order */

    int         nChildXids;     /* # of subcommittedchildXIDs */

    int         maxChildXids;   /* allocated size of childXids[]*/

    Oid         prevUser;       /* previous CurrentUserId setting*/

    int         prevSecContext; /* previous SecurityRestrictionContext */

    bool        prevXactReadOnly;       /* entry-time xactr/ostate */

    bool        startedInRecovery;      /* did we start in recovery? */

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

} TransactionStateData;

 

typedef TransactionStateData *TransactionState;

 

/*

 * CurrentTransactionState always points to thecurrent transaction state

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

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

 */

static TransactionStateData TopTransactionStateData= {

    0,                          /* transaction id */

    0,                          /* subtransactionid */

    NULL,                       /* savepointname */

    0,                          /* savepointlevel */

    TRANS_DEFAULT,              /* transaction state */

    TBLOCK_DEFAULT,             /* transaction block state fromthe client

                                 * perspective */

    0,                          /* transaction nesting depth */

    0,                          /* GUC context nesting depth */

    NULL,                       /* cur transaction context */

    NULL,                       /* cur transaction resource owner*/

    NULL,                       /* subcommittedchild Xids*/

    0,                          /* # of subcommittedchild Xids*/

    0,                          /* allocated size of childXids[]*/

    InvalidOid,                 /* previous CurrentUserId setting*/

    0,                          /* previousSecurityRestrictionContext */

    false,                      /* entry-time xactr/ostate */

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

    LocalTransactionId localTransactionId;      /* backend-localtransaction

                                                 * 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; /* eventspending from each query */

    int         maxquerydepth/* allocated lenof abovearray */

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

 

    /* these fields are just for resetting at subtransabort: */

 

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

} AfterTriggersData;

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

 *  transactionstates - 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.iyunv.com


  

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-303123-1-1.html 上篇帖子: 基于postgresql的自动报表生成工具---一种基于OOSE的方法 下篇帖子: 关于连接PostgreSQL时提示 FATAL: password authentication failed for user "连接用户名" 的解决方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表