【参赛作品65】MOGDB/openGauss的txid_snapshot 数据类型和相关函数

作者:阎书利
txid_snapshot的文本表示为:xmin:xmax:xip_list。

名称      	描述                                      
xmin    	最早的事务ID(txid)仍然活动。所有较早事务将是已经提交可见的,或者是直接回滚。
xmax    	作为尚未分配的txid。所有大于或等于此txids的都是尚未开始的快照时间,因此不可见。
xip_list	当前快照中活动的txids。这个列表只包含在xmin和xmax之间活动的txids;有可能活动的txids高于xmax。 介于大于等于xmin、小于xmax,并且不在这个列表中的txid,在这个时间快照已经完成的,因此按照提交状态查看他是可见还是回滚。这个列表不包含子事务的txids。

示例:10:20:10,13,15意思为:xmin=10, xmax=20, xip_list=10, 13, 15。

测试如下:

1.通过设置强制对临时对象使用COMMIT而不是2PC

SET enforce_two_phase_commit TO off; 

2.正常案例演示

 postgres=# select '12:13:'::txid_snapshot;
    ##  txid_snapshot
     12:13:
    (1 row)
    
    postgres=# select '12:18:14,16'::txid_snapshot;
    ##  txid_snapshot
     12:18:14,16
    (1 row)

3.错误案例演示

postgres=# select '31:12:'::txid_snapshot;
    ERROR:  invalid input for txid_snapshot: "31:12:"
    LINE 1: select '31:12:'::txid_snapshot;
                   ^
    CONTEXT:  referenced column: txid_snapshot
-------------------------------------------------------------------------------
 postgres=# select '0:1:'::txid_snapshot;
    ERROR:  invalid input for txid_snapshot: "0:1:"
    LINE 1: select '0:1:'::txid_snapshot;
                   ^
    CONTEXT:  referenced column: txid_snapshot
-------------------------------------------------------------------------------
postgres=# select '12:13:0'::txid_snapshot;
   ERROR:  invalid input for txid_snapshot: "12:13:0"
   LINE 1: select '12:13:0'::txid_snapshot;
                  ^
   CONTEXT:  referenced column: txid_snapshot
-------------------------------------------------------------------------------
 postgres=# select '12:16:14,13'::txid_snapshot;
    ERROR:  invalid input for txid_snapshot: "12:16:14,13"
    LINE 1: select '12:16:14,13'::txid_snapshot;
                   ^
    CONTEXT:  referenced column: txid_snapshot
-------------------------------------------------------------------------------
postgres=# select '12:16:14,14'::txid_snapshot;
    ERROR:  invalid input for txid_snapshot: "12:16:14,14"
    LINE 1: select '12:16:14,14'::txid_snapshot;
                   ^
    CONTEXT:  referenced column: txid_snapshot

通过测试看出xmax应该大于xmin,不可为0,tixds应该按增序排列,且不为0,并且不能有重复的tixds,在使用的时候应当尽量避免。

4.创建测试表及测试数据导入

 postgres=# create temp table snapshot_test(nr integer,snap txid_snapshot);
    CREATE TABLE
    postgres=# insert into snapshot_test values (1, '12:13:');
    INSERT 0 1
    postgres=# insert into snapshot_test values (2, '12:20:13,15,18');
    INSERT 0 1
    postgres=# insert into snapshot_test values (3, '100001:100009:100005,100007,100008');
    INSERT 0 1
    postgres=# insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131');
    INSERT 0 1

查询数据情况:

postgres=# select snap from snapshot_test order by nr;
                                                                    snap
    -------------------------------------------------------------------------------------------------------
    ------------------------------
     12:13:
     12:20:13,15,18
     100001:100009:100005,100007,100008
     100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,12
    4,125,126,127,128,129,130,131
    (4 rows)

5.函数测试

txid_snapshot_xmin()为会返回快照的xmin,

txid_snapshot_xmax()会返回快照的xmax,

txid_snapshot_xip()获取正在进行的事务ip,即txids。

postgres=# select  txid_snapshot_xmin(snap),
    postgres-# txid_snapshot_xmax(snap),
    postgres-# txid_snapshot_xip(snap)
    postgres-# from snapshot_test order by nr, 1, 2, 3;
     txid_snapshot_xmin | txid_snapshot_xmax | txid_snapshot_xip
    --------------------+--------------------+-------------------
                     12 |                 20 |                13
                     12 |                 20 |                15
                     12 |                 20 |                18
                 100001 |             100009 |            100005
                 100001 |             100009 |            100007
                 100001 |             100009 |            100008
                    100 |                150 |               101
                    100 |                150 |               102
                    100 |                150 |               103
                    100 |                150 |               104
                    100 |                150 |               105

txid_visible_in_snapshot()会查看在快照中事务ID是否可见(不使用子事务ID)

postgres=# select id, txid_visible_in_snapshot(id, snap)
    postgres-# from snapshot_test, generate_series(11, 21) id
    postgres-# where nr = 2;
     id | txid_visible_in_snapshot
    ----+--------------------------
     11 | t
     12 | t
     13 | f
     14 | t
     15 | f
     16 | t
     17 | t
     18 | f
     19 | t
     20 | f
     21 | f
    (11 rows)

6.其他测试

测试二分查找

postgres=# select id, txid_visible_in_snapshot(id, snap)
postgres-# from snapshot_test, generate_series(90, 160) id
postgres-# where nr = 4;
 id  | txid_visible_in_snapshot
-----+--------------------------
  90 | t
  91 | t
  92 | t
  93 | t
  94 | t
  95 | t
  96 | t
  97 | t
  98 | t
  99 | t
 100 | t
 101 | f

测试当前值

postgres=# select txid_current() >= txid_snapshot_xmin(txid_current_snapshot());
##  ?column?
 t
(1 row)

我们不能假设当前值总是小于xmax

  postgres=# select txid_visible_in_snapshot(txid_current(), txid_current_snapshot());
    ##  txid_visible_in_snapshot
     f
    (1 row)

测试64bitness(MOGDB/openGauss将transactionid由int32改为了int64,64位的xid永远不可能耗尽,虽然xid改为了64位,但是过期的xid依旧需要freeze清理,只是永远不用担心会发生xid回卷宕机的风险。 )

postgres=# select txid_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013';

##   txid_snapshot

 1000100010001000:1000100010001100:1000100010001012,1000100010001013
(1 row)


postgres=# select txid_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013');

##  txid_visible_in_snapshot

 f
(1 row)



postgres=# select txid_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013');

##  txid_visible_in_snapshot

 t
(1 row)

测试溢出64bit,9223372036854775807是是263-1,是乘方 也就是63位的最大二进制数字 。

  postgres=# SELECT txid_snapshot '1:9223372036854775807:3';
    ##       txid_snapshot
     1:9223372036854775807:3
    (1 row)
    
    postgres=# SELECT txid_snapshot '1:9223372036854775808:3';
    ERROR:  invalid input for txid_snapshot: "1:9223372036854775808:3"
    LINE 1: SELECT txid_snapshot '1:9223372036854775808:3';
                                 ^
    CONTEXT:  referenced column: txid_snapshot
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gauss松鼠会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值