事务简介

  • 事务管理器:有限状态机

    • 日志管理器

      • CLOG:事务的执行结果
      • XLOG:undo/redo日志
    • 锁管理器:实现并发控制,读阶段采用MVCC,写阶段采用锁控制实现不同的隔离级别

PostgreSQL为每条事务创建一个postgre进程,并发执行事务。采用分层的机制执行事务,上层事务块和底层事务。上层事务块是用户眼中的事务,用于控制事务执行的状态;底层事务是事务中的每条语句,可以改变上层事务块的状态。

上层事务块

每个postgre进程只有一个事务块,上层事务块记录着本次事务执行过程中的各个状态。

typedef enum TBlockState
{
/* not-in-transaction-block states */
TBLOCK_DEFAULT, /* idle */
TBLOCK_STARTED, /* 执行简单查询事务 */ /* transaction block states */
TBLOCK_BEGIN, /* 遇见事务开始BEGIN */
TBLOCK_INPROGRESS, /* 事务正在执行中 */
TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
TBLOCK_END, /* 遇见事务结束COMMIT/END的时候设置 */
TBLOCK_ABORT, /* 事务出错,等待ROLLBACK */
TBLOCK_ABORT_END, /* 事务出错,收到ROLLBACK */
TBLOCK_ABORT_PENDING, /* 事务处理中,接收到ROLLBACK */
TBLOCK_PREPARE, /* 事务处理中,收到PREPARE(分布式事务) */ /* subtransaction states */
TBLOCK_SUBBEGIN, /* starting a subtransaction */
TBLOCK_SUBINPROGRESS, /* live subtransaction */
TBLOCK_SUBRELEASE, /* RELEASE received */
TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
} TBlockState;

常见的事务块状态转换图

  • startTransactionCommand:事务块中每条语句执行前都会调用。
  • commitTransactionCommand:事务块中每条语句执行结束都会调用
  • abortCurrentTransaction:事务块中语句执行错误,在调用点调用
  • BeginTransactionBlock:遇见BEGIN命令调用,状态变为TBLOCK_BEGIN
  • EndTransactionBlock:遇见END调用,可能成功提交,也可能回滚
  • AbortTransactionBlock:遇见ABORT指令调用

底层事务

底层事务是需要执行的每条命令,负责处理资源和锁的获取和释放,信号的处理,日志记录等等

typedef enum TransState
{
TRANS_DEFAULT, /* idle */
TRANS_START, /* transaction starting */
TRANS_INPROGRESS, /* inside a valid transaction */
TRANS_COMMIT, /* commit in progress */
TRANS_ABORT, /* abort in progress */
TRANS_PREPARE /* prepare in progress */
} TransState;

主要有四个函数:

  • StartTransaction:由BEGIN的startTransactionCommand调用,调用结束后事务块状态为TBLOCK_STARTED
  • CommitTransaction:由END的commitTransactionCommand调用,提交事务
  • AbortTransaction和CleanupTransaction:释放资源,恢复默认状态

分布式事务

PostgreSQL提供了分布式事务中的,两阶段提交的接口

并发控制

PostgreSQL采用MVCC的方式进行并发控制,每个事务看到的是一段时间前的数据快照。同时,MVCC并不能够解决所有问题,所以也提供了行级和表级的锁。

标准的事务隔离级别有4个,而PostgreSQL只实现了读已提交和可串行化。

PostgreSQL实现了8种锁(可怕)

太多了,就记住几个吧。

  • 行共享锁:select for update/for share
  • 表共享锁:select
  • 行排他锁:insert/update/delete
  • 表排他锁:drop

加锁的对象

    • 表锁
    • 会话锁
    • 扩展锁:新增表空间
  • 页:对索引页面
  • 元组:
  • 事务:

死锁处理

  • postgresql检测出最后一个等待的杀掉,oracle是第一个等待的杀掉
  • 死锁检测算法(等待图)

MVCC

关键词:

  • 基于事务ID
  • 行级多版本
  • 无回滚段,行内存储
    • 一次UPDATE,产生记录两个版本
    • 两个版本都存在页面内部
typedef struct HeapTupleFields
{
TransactionId t_xmin; /* Insert,Update事务 */
TransactionId t_xmax; /* Delete,Update,Row Locks事务ID */ union
{
CommandId t_cid; /* 操作ID */
TransactionId t_xvac; /* old-style VACUUM FULL xact ID */
} t_field3;
} HeapTupleFields;

cmin:插入该元组的命令在插入事务中的命令标识(从0开始累加)

cmax:删除该元组的命令在插入事务中的命令标识(从0开始累加)

ctid:相当于rowid , <数据块ID,偏移量>

XID:事务ID

Xid_snapshot:当前系统中未提交的事务

CLOG:事务状态日志(已提交的日志)

隔离级别

  1. RC:读已提交

    1. 两个事务可以并发更新同一行
    2. 一个事务更新,一个事务删除同一行,删除操作会上锁
  2. RR:读未提交,其实是snapshot isolation,(冲突状态会回滚)
  3. 可串行化:serialize snapshot isolation,比标准可串行化要高,通过加内存中的意向锁实现,不允许预加锁的数据被其他事务变更

数据可见性判断

  1. 记录的头部XID信息比当前事务更早(rr和ssi有这个要求,read commited没有这个要求,读已经提交可以读未来的事务!!)
  2. 记录头部的XID信息不在当前的XID_snapshot中,(记录上的事务状态不是未提交的事务)
  3. 记录头部的XID信息在CLOG中代表已提交。
  • MVCC需要判断该行数据在这个事务中的有效性,可见性,可更新性(需要锁的帮助才能正确执行隔离级别)
  • 判断条件:若xmin等于当前事务ID,则包含所有xmax=0(未被删除)的元组。

    若与xmin相等的事务ID对应的事务已经被提交,则包含所有xmax=0或xmax为当前事务ID的元组。
  • 实现概要
    • 对读不用加锁,对写加锁(只阻塞写),事务结束对比是否冲突

多行数据需要过期版本回收

  1. 页面级:页面访问时回收
  2. 表级/系统级: autovacuum; vacuum

日志

  1. pg_log:数据库活动日志(也就是数据库的操作日志);
  2. pg_xlog:事务日志,记录事务的执行过程,redo日志
  3. pg_clog:事务状态日志(pg_clog是pg_xlog的辅助日志),记录事务的结果。

PostgreSQL事务实现的更多相关文章

  1. postgresql事务

    查看更多教程:http://www.gitbook.net/postgresql/2013080567.html pgsql事务与并发控制 事务与并发控制 数据库几大特性: ACID: Atomici ...

  2. Odoo 后端数据库postgreSQL事务级别

    Table of Contents 事务的特性 并行事务的问题 事务隔离级别 Odoo事务隔离级别 odoo事务控制         事务的特性 事务4个特性,简写未ACID 原子性(Atomicit ...

  3. PostgreSQL 事务管理的MVCC

    PostgreSQL的并发控制机制同时实现了多版本控制MVCC协议和两阶段封锁协议.实际采用哪种协议取决于所执行的语句类型. DML语句的并发控制将使用MVCC协议: DDL语句的并发控制基于标准的两 ...

  4. postgresql - 事务

    1.事务的使用 begin;//开启关闭自动提交的事务 insert into testtab01 values(0); rollback;//事务回滚 2.SavePoint的使用 begin;// ...

  5. PostgreSQL事务特性之嵌套事务

    嵌套事务的实现是基于SAVEPOINT.ROLLBACK TO SAVEPOINT和RELEASE SAVEPOINT的,也就是设置一个保存点,可以回滚到保存点和释放保存点. 测试表的初始状态如下: ...

  6. PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(5)

    2.5 XLOG的内部结构 我们将使用事务贯穿本书,并让您在技术层面上更深地洞察事情是如果工作的,我们已经增加了这部分专门处理XLOG的内部工作机制.我们会尽量避免前往下降到C级,因为这将超出本书的范 ...

  7. PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(3)

    2.3 理解一致性和数据丢失 挖掘PostgreSQL事务日志而不考虑一致性是不可能的.在本章的第一部分,我们已经大体上解释了事务日志的基本思想.您已经知道,无需事先的日志改变的能力,使数据处于一种好 ...

  8. PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(2)

    2.2 XLOG和复制 在本章中,您已经了解到PostgreSQL的事务日志已经对数据库做了所有的更改.事务日志本身被打包为易用的16MB段. 使用这种更改集来复制数据的想法是不牵强的.事实上,这是在 ...

  9. PostgreSQL的9.4已经发布(译)

    http://www.postgresql.org/about/news/1557/ 2014年12月18日,PostgreSQL全球开发小组发布PostgreSQL9.4,PostgresQL是世界 ...

随机推荐

  1. Python开发——变量

    变量的作用 把程序运行的中间结果,临时保存到内存里,以备后面的代码继续调用 变量的声明 name = “yuan” 变量的定义规则 1.变量名只能是  字母.数字或下划线的任意组合 2.变量名的第一个 ...

  2. class空格多类名

    1.class属性唯一但是有空格,选择空格两边唯一的哪一个 <div id="tempConfigTable" class="dtb-style-1 table-d ...

  3. PAT 甲级 1002 A+B for Polynomials (25 分)

    1002 A+B for Polynomials (25 分) This time, you are supposed to find A+B where A and B are two polyno ...

  4. webplus知识点小结

    1.返回首页,要在首页栏目里面加链接,直接预览站点的时候地址栏那个地址就行 2.上传图片变色问题,要传jpg格式,不要png 3.留言板制作:后台组件管理->留言板->获取链接 然后在留言 ...

  5. tian_lie

    后台托管:nohup ./re_start_job.sh kg_fk_etl >>log.log 2>&1 & 查看进程:ps -ef|grep kg_fk_etl ...

  6. mySQL安装与基础配置

    关系型数据库介绍 数据结构模型 数据结构模型主要有: 层次模型 网状结构 关系模型 关系模型: 二维关系:row,column 数据库管理系统:DBMS 关系:Relational,RDBMS RDB ...

  7. linux的system () 函数详解

    linux的system () 函数详解     system(执行shell 命令)相关函数        fork,execve,waitpid,popen表头文件        #i nclud ...

  8. 2019.02.21 bzoj1249: SGU277 HERO 动态凸包(set+凸包)

    传送门 题意:动态插入点,维护凸包面积. 思路:用setsetset维护极角序来支持面积查询即可. 然后注意选原点的时候要从初始三个点随机平均系数来避免精度误差. 代码: #include<bi ...

  9. Linux 第六天

    1)locate 在文件资料库中查找文件(需要文件资料库中有,新建的文件查不到,需要手动更新,updatedb.查不到/tmp目录下的文件) 语法:locate 文件名 常用选项: -i:无视大小写查 ...

  10. J2CACHE 两级缓存框架

    概述 缓存框架我们有ehcache 和 redis 分别是 本地内存缓存和 分布式缓存框架.在实际情况下如果单台机器 使用ehcache 就可以满足需求了,速度快效率高,有些数据如果需要多台机器共享这 ...