博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
事务xmin,xmax
阅读量:6976 次
发布时间:2019-06-27

本文共 2003 字,大约阅读时间需要 6 分钟。

原理:在元组的头部记录着2个特殊的标记值,xmin和xmax;xmin表示插入该元组的事务号,xmax表示删除该元组的事务号
执行select查询时,会首先获取一个数据库快照,该快照也包括xmin和xmax,这里的xmin表示当前已完成的事务的最小id,xmax表示正在执行的事务的最大id,任何小于xmin的事务被认为已完成,任何大于xmax的事务被认为尚未结束;位于xmin与xmax之间的事务可能已经完成,也可能尚未完成,视情况而定。
扫描元组时,通过对比元组头的xmin、xmax与快照的xmin、xmax,就可以知道这条元组对当前事务是可见还是不可见了。
1.oid 
oid是object identifier的简写,其相关的参数设置default_with_oids设置一般默认是false,或者创建表时指定with (oids=false),其值长度32bit,实际的数据库系统应用中并不能完全保证其唯一性; 
2.tableoid 
是表对象的一个唯一标识符,可以和pg_class中的oid联合起来查看 
3.xmin 
是插入的事务标识符,是用来标识不同事务下的一个版本控制。每一次更新该行都会改变这个值。可以和mvcc版本结合起来看 
4.xmax 
是删除更新的事务标识符,如果该值不为0,则说明该行数据当前还未提交或回滚。比如设置begin事务时可以明显看到该值的变化 
5.cmin 
插入事务的命令标识符,从0开始 
6.cmax 
删除事务的命令标识符,或者为0 
7.ctid 
是每行数据在表中的一个物理位置标识符,和oracle的rowid类似,但有一点不同,当表被vacuum full或该行值被update时该值可能会改变。所以定义表值的唯一性最好还是自己创建一个序列值的主键列来标识比较合适。不过使用该值去查询时速度还是非常快的。 
--在一个客户端执行如下语句
--获取当前事务id,txid_current()每执行一次都会加1
mydb=# select txid_current();
 txid_current 
--------------
         1857
(1 row)
mydb=# begin;
--删除一条数据
mydb=# delete from t where id=2;                 
--可以看到当前事务的id为1858,在另一个session中,可以看到被删除数据的XMAX应为1858
mydb=# select id,name,xmin,xmax,cmin,cmax,txid_current() from t;
 id | name | xmin | xmax | cmin | cmax | txid_current 
----+------+------+------+------+------+--------------
  3 | rudy | 1849 |    0 |    1 |    1 |         1858
                               
--插入一条数据
mydb=# insert into t values(4,'rudy');           
--可以看到被插入数据的xmin为当前事务id
mydb=# select id,name,xmin,xmax,cmin,cmax,txid_current() from t;
 id | name | xmin | xmax | cmin | cmax | txid_current 
----+------+------+------+------+------+--------------
  3 | rudy | 1849 |    0 |    1 |    1 |         1858
  4 | rudy | 1858 |    0 |    1 |    1 |         1858
--在另一外session执行查询,可以看到当前事务ID,大于xmax故可以看到未提交的被删除数据,由于当前事务id大于未提交的插入数据的xmin:1858,故其不可见
mydb=# select id,name,xmin,xmax,cmin,cmax,txid_current() from t;    
 id | name | xmin | xmax | cmin | cmax | txid_current 
----+------+------+------+------+------+--------------
  2 | rudy | 1813 | 1858 |    0 |    0 |         1859
  3 | rudy | 1849 |    0 |    1 |    1 |         1859
(2 rows)
--综上当xmax不为0或null,查询时先比较当前xid是否大于数据的xmax,如果大于xmax则说明数据可见,如果小于或等于数据不可见
--当xmax为0或null时,查查询时比较当前xid是否大于数据的xmin,如果大于则说明数据不可见,如果小于或等于则数据可见

转载地址:http://rjypl.baihongyu.com/

你可能感兴趣的文章
python tar.gz格式压缩、解压
查看>>
JNDI概述(转载)
查看>>
利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换
查看>>
第 7 章 项目运作
查看>>
PYTHON黑帽编程1.5 使用WIRESHARK练习网络协议分析
查看>>
.NET平台开源项目速览(18)C#平台JSON实体类生成器JSON C# Class Generator
查看>>
C# 格式串(收藏)
查看>>
浅谈SQL Server中统计对于查询的影响
查看>>
WF4 Beta,RC版文章总结
查看>>
WPF 与Surface 2.0 SDK 亲密接触–LibraryContainer 篇
查看>>
C# 对应 Oracle 存储过程 的 SYS_REFCURSOR 应该 传入什么类型的参数?
查看>>
Unity3D移植到自己的Android程序
查看>>
【转】用示例说明索引数据块中出现热块的场景,并给出解决方案
查看>>
HDU 2034 人见人爱A-B
查看>>
【AngularJS】—— 12 独立作用域
查看>>
使用工作集(Working Set)整理项目
查看>>
MailMail、RegeX等程序的云端版
查看>>
[Erlang 0072] Erlang XML处理解决方案
查看>>
从C#到Objective-C,循序渐进学习苹果开发(7)--使用FMDB对Sqlite数据库进行操作
查看>>
mmap学习
查看>>