PostgreSQL的并发控制机制同时实现了多版本控制MVCC协议和两阶段封锁协议。实际采用哪种协议取决于所执行的语句类型。

DML语句的并发控制将使用MVCC协议;

DDL语句的并发控制基于标准的两阶段封锁协议。

MVCC的关键思想是维护每一行的不同版本,而不同版本对应着在不同的时间点该行的不同实例。MVCC协议确保每个事务都只看到与事务的数据库视图一致的版本的数据;每个事务看到数据的一个快照,只包含那些在事务启动时已提交的数据。这个快照并不等于数据的当前状态。

使用MVCC的目的 是让读操作不阻塞写操作,写操作不阻塞都操作。读操作访问属于该事务快照的一部分的最近一个版本的行。写操作创建他们独有的隔离的行副本,用于更新。只有两个写操作视图同时更新相同行时,才会出现使得事务阻塞的冲突。相反,使用标准的两阶段时,读操作和写操作都可能被阻塞,因为每个数据库对象只有一个版本,读操作和写操作在访问任何数据前都需要获得相应的锁。

PostgreSQL MVCC的核心是元组的可见性。PostgreSQL的元组指某行的一个版本。元组对事务可见指每个事务都只能访问在其开始运行时已经提交的数据。元组对事务可见的条件:

一个事务标识即transaction ID,在事务启动时分配给每一个事务,同时起到时间戳的作用。

一个叫pg_clog的日志文件,包含每个事务的当前状态。状态分为:处理中,已提交,已中止。

表中每个元组都包含有一个元组头,三个域:

xmin:包含创建该元组的事务标识,又称为创建事务标识(creation-transaction ID);

xmax:包含替换或删除该元组的事务标识(如果没有替换或删除则为null),又称为终止事务标志(expire-transaction ID);

指向相同逻辑行的新版本的前向连接,如果存储。

另外cmin和cmax 标识在同一个事务中多个语句命令的序列值,从0开始,用于同一个事务中实现版本可见性判断。

一个snapshotdata数据结构在事务启动时或查询启动时创建,这取决于隔离级别。snapshotdata数据结构包含在取得快照时所有活跃的事务的列表。

PostgreSQL MVCC带来的影响:

1.给存储管理器带来了额外的负担,因为需要维护元组的不同版本;

2.开发并发应用需要更小心些,因为与使用标准的两阶段封锁协议的系统相比,PostgreSQL MVCC在并发事务运行方式方面带来了一些不同;

3.PostgreSQL的性能取决于运行在其上的工作负载的特点。

创建和存储每一行的多个版本会带来昂贵的存储开销。为了减轻这个问题,PostgreSQL周期性地识别和删除那些不再需要的行的版本,从而释放空间。这个功能以vacuum命令的形式实现。vacuum命令作为一个后台进程运行,也能被用户直接调用。

vacuum命令提供不同的操作模式:

普通的vacuum简单地回收那些不再使用的行所占用的空间,并使这些空间可以重用。这种形式的命令可以和表的普通读写并行执行。

vacuum full命令做了更广泛的处理,包括在块之间移动元组,试图把表压缩到最小数目的磁盘块。这种形式会慢很多,同时对于每一个正在处理的表都需要一个排他锁。

带可选参数analyze调用vacuum时,他将收集正在清理的那些表的内容的统计数据。素以统计结果用来更新pg_statistic系统表,从而允许PostgreSQL查询规划器在规划查询时做更好的选择。

PostgreSQL 事务管理的MVCC的更多相关文章

  1. PostgreSQL事务实现

    事务简介 事务管理器:有限状态机 日志管理器 CLOG:事务的执行结果 XLOG:undo/redo日志 锁管理器:实现并发控制,读阶段采用MVCC,写阶段采用锁控制实现不同的隔离级别 Postgre ...

  2. spring事物配置,声明式事务管理和基于@Transactional注解的使用

    http://blog.csdn.net/bao19901210/article/details/41724355 http://www.cnblogs.com/leiOOlei/p/3725911. ...

  3. 24Spring_事务管理机制

    第一部分:Spring事务管理高层抽象接口 我们介绍三个接口:1.PlatformTransactionManager 2.TransactionDefinition  3.TransactionSt ...

  4. spring+mybatis事务管理

    spring+mybatis事务管理 最近在和朋友做一个项目,考虑用springmvc+mybatis来做,之前在公司工作吧,对于数据库这块的配置也有人再弄,最近因为这个项目,我就上网学习了一些关于数 ...

  5. spring,mybatis事务管理配置与@Transactional注解使用[转]

    spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...

  6. 关系型数据库工作原理-事务管理(二)(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  7. 关系型数据库工作原理-事务管理(一)(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  8. java版云笔记(七)之事务管理

    事务管理 事务:程序为了保证业务处理的完整性,执行的一条或多条SQL语句. 事务管理:对事务中的SQL语句进行提交或者回滚. 事物管理对于企业应用来说是至关重要的,好使出现异常情况,它也可以保证数据的 ...

  9. Spring事务管理—aop:pointcut expression 常见切入点表达式及事物说明

    例: <aop:config>  <aop:pointcut expression="execution(* com.xy.service.*.*(..))"   ...

随机推荐

  1. DateUtil时间工具类

    package utils; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util. ...

  2. MySQL_索引原理与慢查询优化

    索引原理与慢查询优化 创建/删除索引的语法 #方法一:创建表时 CREATE TABLE 表名 ( 字段名1 数据类型 [完整性约束条件…], 字段名2 数据类型 [完整性约束条件…], [UNIQU ...

  3. Eclipse中删除GIT分支

    删除GIT分支: 删除分支时不能直接删除本分支,所以要切换到另一分支,即非删除分支. 1.右击项目——Team——Advanced——Delete Branch...: 2. 在弹出的Delete b ...

  4. MySQL Reading table information for completion of table and column names

    打开数据库是发现提示: mysql> show databases; +--------------------+ | Database | +--------------------+ | b ...

  5. Linux red hat 核心版下安装Nginx

    不要安装核心版的Linux,不要安装核心版的Linux,不要安装核心版的Linux重要的事情要说3遍.心血来潮突然想在Linux下安装Nginx,但是在安装的国程中发现了很多问题.nginx 基本安装 ...

  6. [LeetCode] 860. 柠檬水找零 lemonade-change(贪心算法)

    思路: 收到5块时,只是添加:收到十块时,添加10块,删除一个5块:收到20块时,添加20,删除一个10块一个5块,或者直接删除3个5块(注意:这里先删除5+10优于3个5) class Soluti ...

  7. 利用已有库对excel进行读和写

    读excel的内容:libxls库 C: https://github.com/evanmiller/libxls  或 http://libxls.sourceforge.net/ 参考博客:htt ...

  8. vue-router的创建(1)

    vue-router的创建 <!doctype html> <html lang="en"> <head> <meta charset=& ...

  9. 模块打包机--webpack--基础使用

    什么是webpack? 作用有哪些?   WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,Type ...

  10. Vue父子组件之间的通讯(学习笔记)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...