PostgreSQL快照分析_第1页
PostgreSQL快照分析_第2页
PostgreSQL快照分析_第3页
PostgreSQL快照分析_第4页
PostgreSQL快照分析_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、学号 :年级 :2014届快照和事件处理院(系)名 称 :专 业 名 称 :学 生 姓 名 : 教 师 :二一七年二月目 录1. 问题描述12. 相关介绍12.1 事务12.2 保存点12.3 MVCC23. 代码层面分析43.1 关键的数据结构43.1.1 SnapshotData43.2 AtSubCommit_Snapshot函数53.2.1 函数功能53.2.2 被调用情况53.2.3 代码细节53.3 AtSubAbort_Snapshot函数73.3.1 函数功能73.3.2 被调用情况73.3.3 代码细节73.4 AtEOXact_Snapshot函数83.4.1 函数功能83

2、.4.2 被调用情况83.4.3 代码细节84. 我的收获105. 引用101. 问题描述请详述AtSubCommit_SnapshotAtSubAbort_SnapshotAtEOXact_Snapshot这三个函数的实现细节、功能、调用关系、调用过程等。2. 相关介绍在分析上述过程之前,需要了解一些知识概念,包括事务,保存点,快照等。2.1 事务数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。事务拥有以下四个特性,称之为ACID特性1。 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不

3、执行。 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务。 持久性(Durability):已被提交的事务对数据库的修改永久保存在数据库中。2.2 保存点PostgreSQL在某种程度上来说是不支持事务嵌套的,但是也提供里另外一种技术用于满足类似的应用场景,它支持在当前事务中定义保存点,保存点支持嵌套,用户可以通过保存点来实现事务嵌套相同的功能。PostgreSQL在实现上也包SAVEPOINT认为是定义子事务的标记。保存

4、点是在PostgreSQL中实现的对事务进行更加精细控制的方法。 保存点允许用户在提交事务的过程中,选择性地放弃事务中的特定部分。在使用 SAVEPOINT命令定义一个保存点之后,用户可以在有需要的时候,通过 ROLLBACK 命令回滚至那个保存点。当保存点被回滚时,位于保存点之内的所有数据库修改都会被撤销,但定义保存点之前所做的那些修改则会继续存在。在回滚至一个保存点之后,那个保存点还会继续存在,以便用户在有需要的时候再次进行回滚。与此相反,如果用户确定他们不再需要某个保存点,那么他们也可以释放那个保存点,使得系统可以回收某些与保存点相关的资源。需要注意的一点是,当一个保存点被释放/回滚时,

5、在那个保存点之后定义的所有保存点也会自动被释放/回滚。因为所有这些动作都发生在事务块内部,所以这些动作对于其他数据库会话来说将是不可见的。当用户提交事务块之后,已提交的动作将作为一个整体(unit)变得对外部会话可见;至于那些被回滚了的操作,它们对于外部会话来说永远都是不可见的2。2.3 MVCC在PostgreSQL中是通过使用MVCC,即多版本并发控制技术来实现与传统锁机制有区别的一种并发的方法。传统锁机制实现的事务串行化和并发控制是通过从上之下不断的添加锁,这样必然导致性能的逐渐下降。而MVCC,则做到了读与读不冲突,读与写不冲突,只有写与写才需要锁去控制冲突。不同的读操作根据事务版本的

6、不同,看到的视图是不一样的。因此即使事务A修改某一记录,事务B读到的记录是处于另一版本视图下的,与事务A的写操作自然隔离了,并不需要锁的控制。要完整的了解PostgreSQL中的并发控制过程,还需要了解一些事务隔离方面的知识。在SQL标准中用三个必须在并发的事务之间避免的现象定义了四个级别的事务隔离。这三个现象分别是:l 脏读:一个事务读取了另一个未提交事务写入的数据。l 不可重复读:一个事务重新读取前面读取过的数据,发现该数据已经被另一个已提交事务修改l 幻读:一个事务重新执行一个查询,返回一套符合查询条件的行,发现这些行因为其它最近提交的事务而发生了改变。SQl标准的事务隔离级别如下,其定

7、义是根据这三个实现是否允许发生的状况来决定的:隔离级别脏读不可重复读幻读读未提交可能可能可能读已提交不可能可能可能可重复读不可能不可能可能可串行化不可能不可能不可能在PG中同样也定义了不同的事务隔离级别:隔离级别脏读不可重复读幻读读已提交不可能可能可能可重复读不可能不可能不可能(PG中可重复读已经满足了SQL标准中的可串行化)可串行化不可能不可能不可能*)PG中,读未提交会被在内部映射未读已提交MVCC实现的基本原理就是,每个事务看到的都只是一个特定时间点的数据的快照,从而避免了其他并发更新事务的影响。特点:1)读写不阻塞2)更新相同数据的事务互相阻塞。优点:1)提高并发度2)减少响应时间缺点

8、:1)会给存储造成额外的负担2)容易由并发冲突导致事务回滚PG中,每个事务执行的第一个SQL时系统会根据逻辑时间分配一个唯一的事务ID(又称Xid)通过这个ID就知道了事务发生的先后顺序。那,所谓的MVCC,即多版本并发控制,又是在何处体现呢?显然,就是前面说的“快照”。快照,其实就是相应的版本视图,不同的事务根据事务版本的不同,看到数据库的不同侧面,从而实现读写分离。postgreSQL里快照的抽取十分简单,关键在于两个系统属性:xmin和xmax。在PostgreSQL里,每一个表都默认附加上两个只读的系统属性,xmin和xmax,这两个属性的值共同成为多版本控制的判断条件,所谓快照,实际

9、上就是xmin和xmax满足一定条件的元组集合。xmin如果显示地声明了事务,那么每个事务会自动生成一个事务ID作为标识,即txid;如果没有显示声明,那么每一条独立的语句将生成一个事务ID。当进行insert操作时,插入表新增的元组会额外生成一个xmin属性,其值等于当前的事务ID。换言之,元组的xmin属性的值永远等于其插入表时的事务ID。xmax当插入元组时,xmax属性默认为0,表示未定义。当对该元组进行update或delete操作时,当前事务ID的值会被赋给xmax。PostgreSQL删除元组不会真的从表里删除数据,而是用xmax0来标识该元组被删除。而更新元组也不会直接在原来的

10、元组上进行修改,而分为两步进行:第一步是修改原元组的xmax为当前事务ID;第二步是插入一条新的元组,其所有属性值等于原来元组修改过后的值,xmin为当前事务ID,xmax初始化为0。快照快照就是某时刻下数据库所有元组的xmin和xmax满足一定条件的值的集合。三个事务隔离等级拍摄快照的时机不同,但其判断条件都是一样的。总结一下判断条件:若xmin等于当前事务ID,则包含所有xmax=0(未被删除)的元组。若与xmin相等的事务ID对应的事务已经被提交,则包含所有xmax=0或xmax为当前事务ID的元组。3. 代码层面分析3.1 关键的数据结构该部分涉及的数据结构很多,这里只对最核心的几个数

11、据结构进行分析,分析的内容包括数据结构的含义、关键字段、关键字段的含义。3.1.1 SnapshotData该数据结构表示快照,其主要字段的声明以及描述如下表:字段声明含义SnapshotSatisfiesFunc satisfies;行测试函数指针TransactionId xmin; id小于xmin的所有事务更改在当前快照中可见TransactionId xmax;id大于xmax的所有事务更改在当前快照中可见 TransactionId *xip;所有正在运行的事务的id列表uint32 xcnt;正在运行的事务的计数TransactionId *subxip;进程中子事务的ID列表i

12、nt32 subxcnt;进程中子事务的计数CommandIdcurcid;当前命令的序号uint32 active_count;在活动快照链表里的引用计数uint32 regd_count;在已注册的快照链表里的引用计数3.2 AtSubCommit_Snapshot函数3.2.1 函数功能该函数的主要功能是在提交SubTransaction的时候,处理快照的函数。3.2.2 被调用情况该函数只有一个调用点,CommitSubTransactio()内,该函数的功能是提交SubTransaction,函数执行过程和StartTransaction的执行过程非常的类似。3.2.3 代码细节因为

13、代码量不多,所以这里就详细的将代码执行过程、参数、变量都介绍一遍。整个函数的执行过程如下图所示,首先从活动快照栈顶部获取顶部快照,然后开始遍历,如果遍历到一个活动快照的as_level深度小于当前事务的as_level,则表明该活动快照被父事务标记,因为活动快照进入堆栈的过程是事务嵌套的过程,所以在堆栈中深的活动快照一般都是被父事务标记的。在这里,如果遇到被父事务标记的快照,则跳出循环,如果不是,则将该活动快照重新标记,将其标记设置为该事务的父事务的嵌套深度,即当前事务嵌套深度-1。这么做的主要目的是为了在终止事务的时候根据活动快照被标记的事务嵌套深度来确定哪些快照是需要被清理的。在这短短的几

14、行代码中出现了两个有重要意义的变量,他们分别是:active-as_level、ActiveSnapshot。前者第一次被赋值为当前事务的嵌套深度,之后因为事务的提交或终止操作,这个变量的含义就变为嵌套level的最大值。而后者则为活动快照堆栈顶层元素的指针,通过这个变量可以快速的获取到顶部元素。该函数还有一个参数,根据该函数唯一的调用地址,这个参数代表当前子事务的嵌套深度。3.3 AtSubAbort_Snapshot函数3.3.1 函数功能该函数的主要功能是在子事务被终止之后,清理快照。3.3.2 被调用情况该函数只有一个调用点,即AbortSubTransaction函数,该函数的功能为

15、终止子事务,函数的执行过程和AbortTransaction非常相似,只是作用的对象不同。3.3.3 代码细节函数的执行过程如下图所示:因为该函数的主要功能是清理快照,所以一个很重要的问题便是判断哪些快照应该被清理?这里的判断方法是,如果活动快照被标记的事务嵌套深度大于或者等于被清理的事务的嵌套深度,则表明该快照属于该事务或者该事务的嵌套子事务,这样的快照应该在该嵌套深度的事务被终止的时候都清理掉。又因为考虑到有些快照还会被外层的子事务标记或者注册,所以应该在清理内存的时候判断活动快照的个数和已注册快照的个数,如果两者都为0则表示外层没有事务标记此快照,则应该清理该快照的内存和快照堆栈的内存,

16、否则就应该只清理在该事务中活动快照堆栈元素所占用的内存。这里函数接收的参数依然是要操作的事务的嵌套深度。3.4 AtEOXact_Snapshot函数3.4.1 函数功能该函数的主要功能是在事务结束之后,清理快照。3.4.2 被调用情况函数的调用情况如下,调用者函数功能通过函数名能清楚的反映出来。3.4.3 代码细节函数的执行过程如图:该函数中进行的主要操作包括清理内存和重置相关的参数值,首先检测事务的第一个快照是否为空,如果不为空的话将已注册快照(由资源拥有者管理模块跟踪的的快照)数量-1。之后就开始处理已导出的快照数据,释放快照文件。该函数还有一个参数为isCommit,是否是提交,如果参数为真的话,如果还存在已注册快照或者活动快照则应该讲相关信息作为WARNING写入日志。最后重置一系列的参数,以保证下一次启动新任务时有正确的初始状态。4. 我的收获了解了PostgreSQL和快照相关的概念,包括子事务,保存点,事务嵌套等,并结合代码对这些概念相关功能的实现有了初步的认识。此外,在浏览代码的过程中也深刻的感受到了好的编码习惯对代码可阅读性的影响,PostgreSQL的代码不仅函数变量命名十分的规范,统一,而且函数功能和函数名称有着很强的对应关系,充分体现了良好的命名规范。此外,代码中有许多的注释,这些注释对代码的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论