浅析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数据库事务及行锁特征的更多相关文章
- MySQL数据库 InnoDB引擎 事务及行锁总结
一.事务 1.事务的四大特性 (1)原子性:事务开始后所有的操作要么一起成功,要么一起失败,整个事务是一个不可分割的整体. (2)一致性:是物开始前到结束后,数据库的完整性约束没有被破坏. (3)隔离 ...
- spring学习笔记---数据库事务并发与锁详解
多事务运行并发问题 在实际应用中,往往是一台(或多台)服务器向无数客户程序提供服务,当服务器查询数据库获取数据时,如果没有采用必要的隔离机制,可能会存在数据库事务的并发问题,下面是一些常见的并发问题分 ...
- 多事务运行并发问题spring学习笔记——数据库事务并发与锁详解
多事务运行并发问题 在实际应用中,往往是一台(或多台)服务器向无数客户程序提供服务,当服务器查询数据库获取数据时,如果没有采用必要的隔离机制,可能会存在数据库事务的并发问题,下面是一些常见的并发问题分 ...
- SQL Server 数据库的维护(三)__事务(transaction)和锁
--维护数据库-- --事务(transaction)和锁-- --事务(transaction)-- --概述: 事务是指封装了一组T-SQL语句的单个逻辑单元.单元中的所有语句作为一个整体,在满足 ...
- MySQL中的锁(表锁、行锁)
锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...
- MySQL 行锁 表锁机制
MySQL 表锁和行锁机制 行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整的很惨!不知坑在何方?没事,我来给你们标记几个坑.遇到了可别乱踩.通过本章内容,带你学习MySQL的行锁 ...
- Mysql研磨之InnoDB行锁模式
事务并发带来的一些问题 (1)更新丢失(LostUpdate):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题最后的更新覆盖了由其 ...
- [转]MySQL 表锁和行锁机制
本文转自:http://www.cnblogs.com/itdragon/p/8194622.html MySQL 表锁和行锁机制 行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整 ...
- MySQL学习之——锁(行锁、表锁、页锁、乐观锁、悲观锁等)
转载. https://blog.csdn.net/mysteryhaohao/article/details/51669741 锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是 ...
随机推荐
- 查询oracle数据库里面所有的表名
如果是当前用户,"select * from tab"即可
- 04: Form 验证用户数据 & 生成html
目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...
- java项目报错: org.springframework.beans.factory.BeanCreationException找不到mapper.xml文件
错误代码 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userSer ...
- 20165310java_blog_week6
2165310 <Java程序设计>第6周学习总结 教材学习内容总结 String 构造 String str=new String() String (char a[]) String ...
- noip2015 day1
不解释,很简单,直接按照题目的方法构造就行了 Code #include<iostream> #include<cstdio> #include<cctype> # ...
- Python3基础 os listdir curdir pardir 查看工作目录及其上一级目录的所有文件名
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- POJ 1260 Pearls (斜率DP)题解
思路: 直接DP也能做,这里用斜率DP. dp[i] = min{ dp[j] + ( sum[i] - sum[j] + 10 )*pr[i]} ; k<j<i => dp[j ...
- linux 安装MySql 5.7.20
1.下载文件(https://pan.baidu.com/s/1c1VBcHy)放到目录:/usr/local/ 2.解压 cd /usr/local/ tar -zxvf mysql-5.7.20- ...
- Android程序示例
目录 Android代码示例 OptionsMenu ImageButton CheckBox & RadioButton Context Menu快捷菜单 Key Event ListVie ...
- UVa 1025 城市里的间谍
https://vjudge.net/problem/UVA-1025 题意:一个间谍要从第一个车站到第n个车站去会见另一个,在是期间有n个车站,有来回的车站,让你在时间T内时到达n,并且等车时间最短 ...