暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

聊聊PostgreSQL中Snapshot

141


作者时间QQ技术交流群
perrynzhou@gmail.com2023/03/20672152841







Snapshot
介绍

  • 发起一个事务,这个事务最终只能看到一个版本的行数据,但是PG
    中一个数据页中的一行记录会包含一个或者多个版本数据。所有不同row
    的可见版本构成Snapshot
    .Snapshot
    仅包含创建快照时时提交的数据,从而为这一特定时刻提供了一致的数据视图。




  • 每个事务都有自己的快照,这就意味着不同的事务看到不同的在不同时间点的快照数据。在RR
    隔离级别,快照创建是在第一个事务语句的开始一直到整个事务的完成;而对于RC
    隔离级别快照创建是在事务的每个语句的执行时,并且事务中语句执行期间保持活跃状态


Tuple
可见性

  • PG中的快照并不是物理意义上的数据拷贝而是通过在Tuple Header
    中定义一些字段,其Row
    可见性是由特定的规则决定。PG中每一行数据都包含Tuple Header
    Tuple header
    定义了xmin(数据插入的事务好)
    xmax(删除行数据时候的事务ID)
    、相关的提示位。快照中的每行数据仅仅由一个版本的行数据表示。

  • 行课件的规则相对比较复杂,我们这里可以简单的说明下。快照中一行数据可见的规则是事务开始之前Tuple Header
    中的xmin
    可变动但是xmax
    必须不能变动且事务commited
    ,这表明可见的tuple
    没有被删除。在事务内部,本事务是可以看到未提交的数据变更,如果事务aborted
    ,这行数据变更在任何快照中都不可见






  • 事务2是在快照创建之前提交,因此事务2对于行数变更可见;事务1的活跃时间持续到了快照创建,因此事务1对于行数变更不可见;事务3开始在快照创建之后,因此事务3对于行数据变更不可见


Snapshot
结构


  • snapshot
    在PG源码中的结构是由struct SnapshotData
    表示,快照被创建时候这个结构中部分字段被初始化。新开启的xid
    (事务ID)小于SnapshotData->xmin
    (下边界)行数据可见;事务ID大于等于SnapshotData->xmax
    行数据不可见

  • 在实际中事务的ID在SnapshotData->xmin<= XID <=SnapshotData->xmax
    且该事务不在SnapshotData->xip
    中,该事务是可以看到快照中的行数据的。


typedef struct SnapshotData
{
// 快照类型
SnapshotType snapshot_type; /* type of snapshot */

// 事务ID小于min,tuple都可见
TransactionId xmin;
// 事务ID大于xmax,tuple不可见
TransactionId xmax;
// 当前所有的活跃事务的ID列表
TransactionId *xip;
// 活跃事务的个数
uint32 xcnt;

// 活跃的子事务列表
TransactionId *subxip;
// 走事务的个数
int32 subxcnt; /* # of xact ids in subxip[] */
bool suboverflowed; /* has the subxip array overflowed? */

bool takenDuringRecovery; /* recovery-shaped snapshot? */
bool copied; /* false if it's a static snapshot */

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

/*
* An extra return value for HeapTupleSatisfiesDirty, not used in MVCC
* snapshots.
*/

uint32 speculativeToken;

/*
* For SNAPSHOT_NON_VACUUMABLE (and hopefully more in the future) this is
* used to determine whether row could be vacuumed.
*/

struct GlobalVisState *vistest;

/*
* Book-keeping information, used by the snapshot manager
*/

uint32 active_count; /* refcount on ActiveSnapshot stack */
uint32 regd_count; /* refcount on RegisteredSnapshots */
pairingheap_node ph_node; /* link in the RegisteredSnapshots heap */

TimestampTz whenTaken; /* timestamp when snapshot was taken */
XLogRecPtr lsn; /* position in the WAL stream when taken */

/*
* The transaction completion count at the time GetSnapshotData() built
* this snapshot. Allows to avoid re-computing static snapshots when no
* transactions completed since the last GetSnapshotData().
*/

uint64 snapXactCompletionCount;
} SnapshotData;
  • 在PG内部实现中,包含了多种不同类型的快照类型,具体含义参照如下



文章转载自存储内核技术交流,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论