MOGDB/openGauss的txid_snapshot 資料型別和相關函式

T1YSL發表於2021-12-21

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是是2 63-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


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69990629/viewspace-2848690/,如需轉載,請註明出處,否則將追究法律責任。

相關文章