tongyi007 发表于 2016-11-21 07:44:43

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

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



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



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 areused only for MVCC snapshots, and are normally
     * just zeroes in specialsnapshots.  (But xminand xmaxare used
     * specially byHeapTupleSatisfiesDirty.)
     *
     * An MVCC snapshot cannever see the effects of XIDs >= xmax. It can see
     * the effects of all older XIDs except thoselisted in the snapshot.
xmin
     * is stored as anoptimization to avoid needing to search the XID arrays
     * for most tuples.
     */
    TransactionId xmin;         /* all XID < xminare visible to me */
    TransactionId xmax;         /* all XID >= xmaxare invisible to me */
    uint32     xcnt;         /* # of xactidsin xip[] */
    TransactionId *xip;         /* array of xactIDs in progress */
    /* note: all idsin xip[]satisfy xmin<= xip < xmax*/
    int32      subxcnt;      /* # of xactidsin subxip[] */
    TransactionId *subxip;      /* array of subxactIDs in progress */
    bool       suboverflowed;    /* has the subxiparray overflowed?*/
    bool       takenDuringRecovery; /*recovery-shaped snapshot? */
 
    /*
     * note: all idsin subxip[]are >= xmin, but we don't bother filtering
     * out any that are >= xmax
     */
    CommandId  curcid;           /* in my xact, CID < curcidare visible*/
    uint32     active_count; /* refcounton ActiveSnapshot stack*/
    uint32     regd_count;       /* refcountonRegisteredSnapshotList */
    bool       copied;           /* false if it's a static snapshot */
} SnapshotData;
 
这里面最复杂的是在序列化隔离级别下事务的正常运转,部分体现在RegisterSerializableTransaction方法调用了RegisterSerializableTransactionInt方法,其流程图在下面


 
RegisterSerializableTransactionInt流程图
 
RegisterSerializableTransactionInt里,利用predicatelock相关的哈西表,PredXactListData、PredXactListElementData等组成的链表结构,RWConflictPoolHeaderData、RWConflictData等组成的链表结构等一起管理predicate lock和serializablexact结构,(具体个数据结构参见《PostgreSQL启动过程中的那些事七:初始化共享内存和信号九:shmem中初始化Predicate锁》)利用可序列化快照隔离(Serializable SnapshotIsolation (SSI)),实现了事务的完全可序列化隔离级别,以支持该事务隔离级别下事务的正常运转。
 
              利用可序列化快照隔离(Serializable Snapshot Isolation (SSI))的相关情况最初是在下面的论文里描述:
    MichaelJ. Cahill, UweR枚hm, and AlanD. Fekete. 2008.
    Serializableisolation for snapshot databases.
    InSIGMOD '08: Proceedings of the 2008 ACM SIGMOD
    internationalconference on Management of data,
    pages729-738, New York, NY, USA. ACM.
    http://doi.acm.org/10.1145/1376616.1376690
在下面的博士论文里做了进一步阐述。
    MichaelJames Cahill. 2009.
    SerializableIsolation for Snapshot Databases.
    SydneyDigital Theses.
    University of Sydney, School of Information Technologies.
    http://hdl.handle.net/2123/5353
就到这儿吧。
 
  

  

  

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

  


        
页: [1]
查看完整版本: PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照