浅析postgresql数据库事务及行锁特征
Posted 数据库生态圈(RDB & NoSQL & Bigdata)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析postgresql数据库事务及行锁特征相关的知识,希望对你有一定的参考价值。
开源数据库领域,postgresql以其优越的性能、功能及良好的稳定性排名首位可谓当之无愧,尤其是对高并发的支持可谓匠心独具。而优越的性能和稳定性,究其根本无非是良好的基础架构,本文将对其性能和稳定性有着良好支撑的事务及锁机制进行探讨,并结合实际测试,以真切说明和证明其特点。
1、可在事务中的DDL
postgresql中,DDL语句可以在事务中,既可以提交,也可以回滚,这在实际工作中,不然具备很大的实际意义,也会给工作带来方便和安全,如下图所示:
2、mvcc
postgresql中,很好的实现了mvcc功能,postgresql中mvcc实现了读写不阻塞,同时也说明了相同数据行上的写写阻塞,如下图所示:
session1:开始一个事务,事务中insert into t1中一条数据,但不提交,也不会滚,如图:
session2:此时另开一个会话,连接到相同的用户和数据库,也insert into t1中同样的数据行,此时,该事务被阻塞,表现为在该会话中挂住,如图:
session1:在回到session1中,此时发出commit命令,如图:
session2:在回到session2中,此时,因为session1中的相同数据被成功insert并提交,因为t1表c2字段上有主键,因此,session2中的insert into t1事务失败,并报错,如图:
3、mvcc实现机制
虽然目前的关系库都实现了mvcc功能,但因为底层架构和设计的因素,有些导致系统稳定性和性能方面的不足。而postgresql中,该功能的实现可谓非常巧妙,这也是postgresql号称免费版的Oracle的重要因素之一。因为mvcc功能,postgresql中相同数据行的读写不阻塞,而写写会阻塞和等待。那么,postgresql中是如何实现了mvcc功能的呢?postgresql中,主要通过数据行上的几个隐含字段实现了mvcc功能,他们分别是:xmin,amax,cmin,cmax,如下图所示:
session1:在此会话中,开始一个事务,并在事务中分别update字段c1=1和delete字段c1=2的两个数据行,期间分别查询t1中每个数据行的数据和隐含字段:
session2:打开另一个会话session2,并连接到相同的数据库和用户,在session1中delete、update、commit操作后,分别查询表t1中数据行和几个隐藏列的值,可以发现:session1中,update数据行前insert的数据行,只填写了xmin隐藏列的值,并且是当时的xid;update操作时,将旧数据行的xmax填写为update事务的xid,并重新insert一行新数据,且将新数据行的xmin填写为当前事务xid,session1中update后查到的数据是新数据行(xmin为当前事务xid),而因为session1中update未提交,session2中查到的数据行为旧数据行(xmin为之前第一次insert时的xid,xmax为当前事务的xid);delete操作时,会将旧数据行的xmax填写为当前事务的xid,在session1中查询时,因为已经删除,已经查不到该数据行,而在session2中,因为session1中的delete操作并未提交,所以看到的是删除前的数据行,但此时看到旧数据行的xmax已被填写为session1中事务的xid。session1中提交后,session2中再也看不到旧数据行,只看到了update和delete后的结果,如图所示:
这样postgresql通过数据行的几个隐藏列巧妙的实现了mvcc功能;而同样的mvcc功能,oracle虽然实现的很优雅,但需要到undo段中获取改变向量以重构数据块的前影像,这也许会消耗掉一部分系统资源;mysql的innodb中,虽然不需要重构数据块前影像,但也需要到undo空间获取旧的数据行;db2和sql server库中,虽然也实现了类似mvcc功能,但db2中,通过redo信息重构数据前影像,这可能会使得redo变得过热和拥塞,sql server则是将前影像信息放到了temp数据库中。postgresql中mvcc的功能虽然实现的巧妙,且在获取旧数据行的过程中不会消耗太多系统资源,但也存在不同版本数据行都存在数据段内的情况,当这种旧数据太多时,可能会带来性能上的问题,清理这些旧数据时,也可能会导致系统负载和性能的抖动或颠簸。
4、免费版的Oracle当之无愧
postgresql除了行锁实现机制外,事务级别和oracle也非常相似,虽然支持四个标准事务级别的设置,但postgresql实际上只支持两个事务级别:read committed和serializable。此外,postgresql还支持完备的约束,索引,多种语言的函数和过程编码实现,且为进程模型,几乎可以在每个流行的平台上安装使用等,这些特点和功能,足可以说其为免费版的oracle当之无愧。
以上是关于浅析postgresql数据库事务及行锁特征的主要内容,如果未能解决你的问题,请参考以下文章
来了!PostgreSQL 同步流复制原理和代码浅析,请签收
干货分享!CynosDB for PostgreSQL 架构浅析