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
最后修改時間:2021-12-20 15:36:38
「喜歡這篇文章,您的關注和贊賞是給作者最好的鼓勵」
關注作者
【版權聲明】本文為墨天輪用戶原創內容,轉載時必須標注文章的來源(墨天輪),文章鏈接,文章作者等基本信息,否則作者和墨天輪有權追究責任。如果您發現墨天輪中有涉嫌抄襲或者侵權的內容,歡迎發送郵件至:contact@modb.pro進行舉報,并提供相關證據,一經查實,墨天輪將立刻刪除相關內容。




