欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照

程序员文章站 2022-07-12 18:21:48
...

 

话说 查询“ select cname, comp from test1, test2 where test1.id=test2.id; 发送到服务器端, 走查询分支 exec_simple_query ,先调用 start_xact_command 初始化了事务管理相关对象和资源,接着调用 pg_parse_query ,通过 Lex Yacc 对传入 SQL 语句进行词法语法解析,生成解析树。下来调用 GetTransactionSnapshot 方法做内存快照。内存快照和事务隔离级别紧密相关,其中 可重复读和序列化隔离级别每个数据库事务使用一个快照,读未提交和读已提交隔离级别每个语句使用一个快照。序列化隔离级别除快照外还使用 predicate 锁。

 

 

1

下面是做内存快照的调用序列图。


PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照
            
    
    博客分类: PostgreSQL内核 PostgreSQL快照snapshot 

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

 

         上图红色方框中显示了获取内存快照的方法调用过程,在 GetSnapshotData 方法中根据事务隔离级别等情况获取相应快照,一般 可优化语句(增、删、查、改)都需要快照, 然后注册相应快照。下面是获取快照方法 GetTransactionSnapshot 的流程图。


PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照
            
    
    博客分类: PostgreSQL内核 PostgreSQL快照snapshot 

GetTransactionSnapshot 方法流程图

GetTransactionSnapshot() 方法根据事务隔离级别 分别处理取快照的情况。如果事务隔离级别是 读未提交、读已提交, 调用 GetSnapshotData(&CurrentSnapshotData) 方法获取一个快照赋给 CurrentSnapshot ,返回 CurrentSnapshot 。如果事务隔离级别是 可重复读或序列化 ,且是事务里第一次获取快照,直接返回 CurrentSnapshot ;不是第一次且是 可重复读 事务隔离级别,调用 GetSnapshotData(&CurrentSnapshotData) 方法获取一个快照赋给 CurrentSnapshot ,然后 调用 RegisterSnapshotOnOwner(CurrentSnapshot, TopTransactionResourceOwner) 方法 在资源管理器 TopTransactionResourceOwner 里注册这个快照;不是第一次且是 序列化 事务隔离级别, 调用 RegisterSerializableTransaction(&CurrentSnapshotData) 方法,根据需要调用 GetSnapshotData 方法获取快照并调用 RegisterSnapshotOnOwner 方法在资源属主 TopTransactionResourceOwner 上注册快照,并初始化一个可序列化事务 SERIALIZABLEXACT 结构和哈西表 。最后,不管什么情况都返回当前快照,调用 PushActiveSnapshot 方法,把这个快照推入由 ActiveSnapshotElt 构成的 “活跃快照”栈

pg 里快照就是数据结构 SnapshotData ,定义如下,表示某个时刻内存里对象的状态,下面是快照 SnapshotData 结构定义:

typedef struct SnapshotData

{

    SnapshotSatisfiesFunc satisfies ;   /* tuple test function */

 

    /*

      * The remaining fields are used only for MVCC snapshots, and are normally

      * just zeroes in special snapshots.  (But xmin and xmax are used

      * specially by HeapTupleSatisfiesDirty.)

      *

      * An MVCC snapshot can never see the effects of XIDs >= xmax . It can see

      * the effects of all older XIDs except those listed in the snapshot.

xmin

      * is stored as an optimization to avoid needing to search the XID arrays

      * for most tuples.

      */

    TransactionId xmin ;         /* all XID < xmin are visible to me */

    TransactionId xmax ;         /* all XID >= xmax are invisible to me */

    uint32      xcnt ;         /* # of xact ids in xip [] */

    TransactionId * xip ;         /* array of xact IDs in progress */

    /* note: all ids in xip [] satisfy xmin <= xip [i] < xmax */

    int32       subxcnt ;      /* # of xact ids in subxip [] */

    TransactionId * subxip ;      /* array of subxact IDs in progress */

    bool        suboverflowed ;    /* has the subxip array overflowed? */

    bool        takenDuringRecovery ; /* recovery-shaped snapshot? */

 

    /*

      * note: all ids in subxip [] are >= xmin , but we don't bother filtering

      * out any that are >= xmax

      */

    CommandId   curcid ;           /* in my xact , CID < curcid are visible */

    uint32      active_count ; /* refcount on ActiveSnapshot stack */

    uint32      regd_count ;       /* refcount on RegisteredSnapshotList */

    bool        copied ;           /* false if it's a static snapshot */

} SnapshotData ;

 

这里面最复杂的是在序列化隔离级别下事务的正常运转,部分体现在 RegisterSerializableTransaction 方法调用了 RegisterSerializableTransactionInt 方法,其流程图在下面


PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照
            
    
    博客分类: PostgreSQL内核 PostgreSQL快照snapshot 
 

RegisterSerializableTransactionInt 流程图

 

RegisterSerializableTransactionInt 里,利用 predicate lock 相关的哈西表, PredXactListData PredXactListElementData 等组成的链表结构, RWConflictPoolHeaderData RWConflictData 等组成的链表结构等一起管理 predicate lock serializablexact 结构,(具体个数据结构参见 PostgreSQL 启动过程中的那些事七:初始化共享内存和信号九: shmem 中初始化 Predicate 利用可序列化快照隔离( Serializable Snapshot Isolation (SSI) ,实现了事务的 完全可序列化隔离级别,以支持该事务隔离级别下事务的正常运转。

 

              利用可序列化快照隔离( Serializable Snapshot Isolation (SSI) )的 相关情况 最初是在下面的论文里描述:

    Michael J. Cahill , Uwe R hm , and Alan D. Fekete . 2008.

     Serializable isolation for snapshot databases.

     In SIGMOD '08: Proceedings of the 2008 ACM SIGMOD

     international conference on Management of data,

     pages 729-738, New York, NY, USA. ACM.

     http://doi.acm.org/10.1145/1376616.1376690

在下面的博士论文里做了进一步阐述。

    Michael James Cahill . 2009.

    Serializable Isolation for Snapshot Databases.

    Sydney Digital Theses.

    University of Sydney , School of Information Technologies.

    http://hdl.handle.net/2123/5353

就到这儿吧。

 




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


        


  • PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照
            
    
    博客分类: PostgreSQL内核 PostgreSQL快照snapshot 
  • 大小: 98.4 KB
  • PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照
            
    
    博客分类: PostgreSQL内核 PostgreSQL快照snapshot 
  • 大小: 56.7 KB
  • PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照
            
    
    博客分类: PostgreSQL内核 PostgreSQL快照snapshot 
  • 大小: 45.5 KB