七叶笔记 » 数据库 » PostgreSQL数据库事务实现方法分析

PostgreSQL数据库事务实现方法分析

常见的事务块状态转换图

 

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

底层事务

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

主要有四个函数:

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,产生记录两个版本 两个版本都存在页面内部

cmin:插入该元组的命令在插入事务中的命令标识(从0开始累加) cmax:删除该元组的命令在插入事务中的命令标识(从0开始累加) ctid:相当于rowid , <数据块ID,偏移量> XID:事务ID Xid_snapshot:当前系统中未提交的事务 CLOG:事务状态日志(已提交的日志)

隔离级别

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

数据可见性判断

记录的头部XID信息比当前事务更早(rr和ssi有这个要求,read commited没有这个要求,读已经提交可以读未来的事务!!) 记录头部的XID信息不在当前的XID_snapshot中,(记录上的事务状态不是未提交的事务) 记录头部的XID信息在CLOG中代表已提交。 MVCC需要判断该行数据在这个事务中的有效性,可见性,可更新性(需要锁的帮助才能正确执行隔离级别) 判断条件:若xmin等于当前事务ID,则包含所有xmax=0(未被删除)的元组。 若与xmin相等的事务ID对应的事务已经被提交,则包含所有xmax=0或xmax为当前事务ID的元组。 实现概要 对读不用加锁,对写加锁(只阻塞写),事务结束对比是否冲突

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

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

日志

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

希望本文所述对大家PostgreSQL数据库程序设计有所帮助。

相关文章