PostgreSQL数据库事务系统——Push\Pop快照

网友投稿 355 2022-12-02

PostgreSQL数据库事务系统——Push\Pop快照

快照使用快照链栈来保存获取的多个快照。栈的元素是ActiveSnapshotElt结构体,ActiveSnapshot指针指向栈顶,OldestActiveSnapshot指向栈底。

/* Elements of the active snapshot stack. * Each element here accounts for exactly one active_count on SnapshotData. * NB: the code assumes that elements in this list are in non-increasing * order of as_level; also, the list must be NULL-terminated. */typedef struct ActiveSnapshotElt { Snapshot as_snap; int as_level; struct ActiveSnapshotElt *as_next;} ActiveSnapshotElt;/* Top of the stack of active snapshots */static ActiveSnapshotElt *ActiveSnapshot = NULL;/* Bottom of the stack of active snapshots */static ActiveSnapshotElt *OldestActiveSnapshot = NULL;

PushActiveSnapshot

PushActiveSnapshot第一步先申请ActiveSnapshotElt内存,第二步判定形参snap是否是CurrentSnapshot或者SecondarySnapshot,或者没有拷贝过,则需要将该快照拷贝到ActiveSnapshotElt的as_snap快照成员,否则直接将snap赋值给ActiveSnapshotElt的as_snap快照成员。

/* PushActiveSnapshot Set the given snapshot as the current active snapshot * If the passed snapshot is a statically-allocated one, or it is possibly * subject to a future command counter update, create a new long-lived copy * with active refcount=1. Otherwise, only increment the refcount. */void PushActiveSnapshot(Snapshot snap) { ActiveSnapshotElt *newactive; Assert(snap != InvalidSnapshot); newactive = MemoryContextAlloc(TopTransactionContext, sizeof(ActiveSnapshotElt)); /* Checking SecondarySnapshot is probably useless here, but it seems better to be sure. */ if (snap == CurrentSnapshot || snap == SecondarySnapshot || !snap->copied) newactive->as_snap = CopySnapshot(snap); else newactive->as_snap = snap; newactive->as_next = ActiveSnapshot; newactive->as_level = GetCurrentTransactionNestLevel(); newactive->as_snap->active_count++; ActiveSnapshot = newactive; if (OldestActiveSnapshot == NULL) OldestActiveSnapshot = ActiveSnapshot;}

第三步将ActiveSnapshotElt的as_next指向当前栈顶,ActiveSnapshotElt作为当前快照的栈顶,为as_level赋值为GetCurrentTransactionNestLevel(),将快照的active_count自增。(If the passed snapshot is a statically-allocated one, or it is possibly subject to a future command counter update, create a new long-lived copy with active refcount=1. Otherwise, only increment the refcount.)

PopActiveSnapshot

从快照链栈中删除栈顶的元素,并减少快照引用计数,如果引用计数为零,需要释放该栈顶快照。

/* PopActiveSnapshot * Remove the topmost snapshot from the active snapshot stack, decrementing the * reference count, and free it if this was the last reference. */void PopActiveSnapshot(void) { ActiveSnapshotElt *newstack; newstack = ActiveSnapshot->as_next; Assert(ActiveSnapshot->as_snap->active_count > 0); ActiveSnapshot->as_snap->active_count--; if (ActiveSnapshot->as_snap->active_count == 0 && ActiveSnapshot->as_snap->regd_count == 0) FreeSnapshot(ActiveSnapshot->as_snap); pfree(ActiveSnapshot); ActiveSnapshot = newstack; if (ActiveSnapshot == NULL) OldestActiveSnapshot = NULL; SnapshotResetXmin();}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Postgres-xl GTM(全局事务管理器 Globale Transaction Manager)快照管理
下一篇:java开发的工厂方法模式及抽象工厂验证示例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~