3.2 快照
快照(Snapshot)是记录数据库当前瞬时状态的一个数据结构,PostgreSQL数据库的快照主要保存当前的所有活跃事务的最小事务ID、最大事务ID、当前的活跃事务列表、当前事务的CommandID等。快照可以分为多种类型,每种快照类型都对应了一种判断元组可见性的方法。
快照中最重要的信息是xmin、xmax和xip(含subxip),它们可以用来表示当前系统中所有事务所处的状态。
Snapshot->xmin代表的是当前所有活跃事务中的最小事务ID,如果事务ID小于Snapshot-> xmin,则证明这个事务已经提交或异常终止。
Snapshot->xmax的值是借助latestCompletedXid获得的,xmax = latestCompletedXid + 1。每当事务提交时,如果这个事务ID比系统记录的latestCompletedXid更大,则需要更新latestCompletedXid的值为正在提交的这个事务ID。也就是说,latestCompletedXid记录的是所有已提交事务中最大的那个事务ID,这样Snapshot->xmax就比所有已提交事务的事务ID都要大。通俗地说,如果一个事务ID大于等于xmax,就代表这个事务还是活跃事务(或尚未启动)。需要注意的是,这里活跃的含义是获得快照的瞬间事务是活跃的,在快照的存续期间即使这个事务已经提交,快照的内容也不会发生变化。
我们已经知道小于Snapshot->xmin的事务一定已经结束,而大于Snapshot->xmax的事务一定是活跃事务,那么处于Snapshot->xmin和Snapshot->xmax之间的事务呢?这就需要查看正在运行的所有Backends是否有正在运行的事务。如果某个Backends正在运行一个事务,则把它们记录到Snapshot->xip中。也就是说,Snapshot->xip是活跃事务表,它里面保存的是xmin和xmax之间的活跃事务;反之,不在Snapshot->xip列表中的事务一定是结束了的事务。Snapshot->subxip同理。
有了快照和元组的版本信息,就可以借助这些信息进行可见性判断。数据库需要使用不同的方法来判断可见性,所以在SnapshotData结构体中用snapshot_type记录该快照如何判断可见性信息。有些可见性判断方法需要快照信息,例如SNAPSHOT_MVCC;而有些则不需要,例如SNAPSHOT_ANY,在此快照下所有元组都可见,它的可见性判断不依赖快照中的内容。快照类型如表3-1所示。
表3-1 快照类型