暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL事务卷入

墨香溪的溪 2021-08-02
947

前面已知,相当来说,事务ID其实是有限的,2^32次方个,也就是大约40亿多。对于现在繁忙的交易系统来说,可能会很快就用完。

所以我们要对事务ID进行重复利用,也就是把事务ID当作一个环去循环使用它,这里就引入一个问题,事务ID回卷。

这里主要对  http://www.interdb.jp/pg/index.html 第五章第十节的内容进行意译。

在PostgreSQL里面,我们把事务ID 一分为二,把一个事务的前2^31次方个事务当成是过去,后2^31次方当成未来。

假设,我们在txid 等于100 的时候,插入了一行数据,并且提交。也就是t_xmin 为100。运行了很长一段时间以后,由于这一行数据一直没有被修改,所以这一行数据的t_xmin一直都是100。 

当事务A,运行到2^31次方+100 的时候,因为t_xmin=100 对于他来说,是已经提交的过去的数据,所以这时候,它可以成功的读取该行数据。

这时,事务B开始,事务ID为2^31+101, 他能看到的最远的过去变成了101。事务ID 100 变成了他的未来,即不可见。

参见下图:

(就像一个人,他只能回头看到自己踩过的100个脚印,在一个轮子上有201个脚印,他沿着轮子一直走,却永远只能看到自己踩过的100个脚印,对未来的100个脚印,都是不可见的)

这就是事务ID 回卷。

为了解决事务ID回卷的问题,PostgreSQL引入了一个叫冻结txid 的概念。在PostgreSQL中,保留了一个特殊的txid 2 为冻结事务ID。当该行数据的事务ID被定义为2, 意味着该行比当前所有的事务ID都要老,也就是对当前所有的事务可见。

把一行数据冻结是vacuum 要做的事,冻结的过程是把表的文件扫描一遍,如果发现t_xmin的值,比当前活跃的最小的事务ID-vacuum_freeze_min_age(50000000)还要小,那么即将该行冻结。

在9.4版本以前,会把t_xmin 的值设置为2,在9.4及以后版本,会设置t_infomask 的字节位。即

#define HEAP_XMIN_FROZEN        (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)   *位或运算符,表明已经frozen */

参见下图:



文章转载自墨香溪的溪,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论