PostgreSQL之Snapshot

概述

Postgres中快照的作用是什么?我觉得下面一句话应该是简要而中肯的:

快照记录了数据库当前某个时刻的活跃事务列表。通过快照,可以确定某个元组的版本对于当前快照是否可见。

这里面有几个主要的要点是,

对于元组的多版本信息,已有介绍。本文章主要介绍快照及其使用规则。

快照

postgres中快照的主要数据结构如下,它主要描述了某一时刻数据库内所有事务的状态。

typedef struct SnapshotData 
{ 
    SnapshotSatisfiesFunc satisfies;    /* 元组测试函数指针*/ 


    TransactionId xmin;            /* id小于xmin的所有事务更改在当前快照中可见 */ 
    TransactionId xmax;            /* id大于xmax的所有事务更改在当前快照中可见 */ 
    uint32        xcnt;            /* 正在运行的事务的计数 */ 
    TransactionId *xip;            /* 所有正在运行的事务的id列表 */ 
    /* 忽略了其他不关注的字段 */
} SnapshotData;

这个结构体就完整的表达了一个快照。它里边有什么呢?某个时刻点上整个数据库里所有事务的当前状态。首先要知道,数据库中的事务标识xid是递增的。结构体中的两个数值和一个数组将整个事务范围划分为了几个范围:

这里需要注意的是,所有的事务范围被划分为了四个部分,所有活跃事务存储在了一个数组中,它们是一个点的集合,而不是一个连续范围的集合。这一部分的信息完全地表述了文章开始所述的第一点。紧接着,就需要说明与快照相对应的一些规则。不同的判定规则应用于不同的可见性判定,主要提供的判定规则有:

这部分规则的实现就是通过MVCC中所述的元组的可见性判定规则的函数来实现的。

与MVCC的关系

整体来讲,前一文章所述的元组的多版本信息也顶多是提供了一个可以进行并发控制的基础信息,以及不同版本的元组的可见性判定规则; 它需要与本节所述的快照以其规则结合起来,才能够决定一个元组的某个版本是否对一个快照可见的。总体来看,MVCC与Snapshot这二者的关联如下:

参考

Table of Contents