表级隐含字段: Xmin 和 Xmax

PostgreSQL 里每张表都有隐含字段,确切地说应该是 system Columns , 本文主要讲述下其中两个 system columns,即为 xmin , xmax。

官网解释

xmin
The identity (transaction ID) of the inserting transaction for this row version.
(A row version is an individual state of a row; each update of a row creates a new row
version for the same logical row.)

xmax
The identity (transaction ID) of the deleting transaction, or zero for an undeleted
row version. It is possible for this column to be nonzero in a visible row version. That
usually indicates that the deleting transaction hasn it committed yet, or that an attempted
deletion was rolled back.

根据上面讲解,可以知道 xmin,xmax都指事务ID(transaction ID), 简单的说,xmin记录的是当数据插入( Insert )时的事务ID,xmax记录的是当行上的数据有变动(delete or update )时的事务ID,下面看下详细的实验过程。

测试环境准备

创建测试表并插入数据

1
2
3
4
skytf=> create table test_17 (id integer ,name varchar(32));  
CREATE TABLE
skytf=> insert into test_17 select generate_series(1,10),'a';
INSERT 0 10

查询表 test_17信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
skytf=> select xmin,xmax,ctid,* from test_17;  
xmin | xmax | ctid | id | name
----------+------+--------+----+------
14240187 | 0 | (0,1) | 1 | a
14240187 | 0 | (0,2) | 2 | a
14240187 | 0 | (0,3) | 3 | a
14240187 | 0 | (0,4) | 4 | a
14240187 | 0 | (0,5) | 5 | a
14240187 | 0 | (0,6) | 6 | a
14240187 | 0 | (0,7) | 7 | a
14240187 | 0 | (0,8) | 8 | a
14240187 | 0 | (0,9) | 9 | a
14240187 | 0 | (0,10) | 10 | a
(10 rows)

这里看到, 表 test_17 里有十条数据,并且这10条数据的 xmin 都为 14240187 , xmax 值都为 0 14240187 即为事务ID,下面可以进一步地测试

测试场景一:Xmin

开启一事务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
skytf=> begin;  
BEGIN

skytf=> select txid_current();
txid_current
--------------
14240188
(1 row)

skytf=> select txid_current();
txid_current
--------------
14240188
(1 row)

skytf=> insert into test_17 values (11,'b');
INSERT 0 1
skytf=> end;
COMMIT

上面事务提交后,查询 xmin

1
2
3
4
5
skytf=> select xmin,xmax,ctid,* from test_17 where id=11;  
xmin | xmax | ctid | id | name
----------+------+--------+----+------
14240188 | 0 | (0,11) | 11 | b
(1 row)

可以看到 14240188 即为开始 INSERT 数据时的事务ID。

测试场景二:Xmax

查询表 test_17信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
skytf=> select xmin,xmax,ctid,* from test_17;  
xmin | xmax | ctid | id | name
----------+------+--------+----+------
14240187 | 0 | (0,1) | 1 | a
14240187 | 0 | (0,2) | 2 | a
14240187 | 0 | (0,3) | 3 | a
14240187 | 0 | (0,4) | 4 | a
14240187 | 0 | (0,5) | 5 | a
14240187 | 0 | (0,6) | 6 | a
14240187 | 0 | (0,7) | 7 | a
14240187 | 0 | (0,8) | 8 | a
14240187 | 0 | (0,9) | 9 | a
14240187 | 0 | (0,10) | 10 | a
14240188 | 0 | (0,11) | 11 | b
(11 rows)

大家可以看到, xmax 值为0,那什么情况下 xmax 值不为0呢,有几种情况,接下来看

情形一: deleting事务未提交

会话一:开启一事务

1
2
3
4
5
6
7
8
9
10
skytf=> begin;  
BEGIN
skytf=> select txid_current();
txid_current
--------------
14240189
(1 row)
skytf=> delete from test_17 where id=11;
DELETE 1
skytf=>

会话一开启一个事务,并删除一条数据,并不 commit,此时开启另一会话。

另开一个会话查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
skytf=> select xmin,xmax,ctid,* from test_17;  
xmin | xmax | ctid | id | name
----------+----------+--------+----+------
14240187 | 0 | (0,1) | 1 | a
14240187 | 0 | (0,2) | 2 | a
14240187 | 0 | (0,3) | 3 | a
14240187 | 0 | (0,4) | 4 | a
14240187 | 0 | (0,5) | 5 | a
14240187 | 0 | (0,6) | 6 | a
14240187 | 0 | (0,7) | 7 | a
14240187 | 0 | (0,8) | 8 | a
14240187 | 0 | (0,9) | 9 | a
14240187 | 0 | (0,10) | 10 | a
14240188 | 14240189 | (0,11) | 11 | b
(11 rows)

发现 id为 11的记录的 xmax 变为 14240189 了。有兴趣的可以测试下 updating 事务未提交的场景,和这个结果类似,这里不再详述。

情形二: deleting 事务 rollback

开启事务

1
2
3
4
5
6
7
8
9
10
11
skytf=> begin;  
BEGIN
skytf=> select txid_current();
txid_current
--------------
14240190
(1 row)
skytf=> delete from test_17 where id=10;
DELETE 1
skytf=> rollback;
ROLLBACK

再次查询表信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
skytf=> select xmin,xmax,ctid,* from test_17;  
xmin | xmax | ctid | id | name
----------+----------+--------+----+------
14240187 | 0 | (0,1) | 1 | a
14240187 | 0 | (0,2) | 2 | a
14240187 | 0 | (0,3) | 3 | a
14240187 | 0 | (0,4) | 4 | a
14240187 | 0 | (0,5) | 5 | a
14240187 | 0 | (0,6) | 6 | a
14240187 | 0 | (0,7) | 7 | a
14240187 | 0 | (0,8) | 8 | a
14240187 | 0 | (0,9) | 9 | a
14240187 | 14240190 | (0,10) | 10 | a
(10 rows)

发现 id为 10 的记录的 xmax 变为 14240190 了。

情况三: updating 事务 rollback

开启事务

1
2
3
4
5
6
7
8
9
10
11
skytf=> begin;  
BEGIN
skytf=> select txid_current();
txid_current
--------------
14240191
(1 row)
skytf=> update test_17 set name='aaa' where id=1;
UPDATE 1
skytf=> rollback;
ROLLBACK

再次查询表信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
skytf=> select xmin,xmax,ctid,* from test_17;  
xmin | xmax | ctid | id | name
----------+----------+--------+----+------
14240187 | 14240191 | (0,1) | 1 | a
14240187 | 0 | (0,2) | 2 | a
14240187 | 0 | (0,3) | 3 | a
14240187 | 0 | (0,4) | 4 | a
14240187 | 0 | (0,5) | 5 | a
14240187 | 0 | (0,6) | 6 | a
14240187 | 0 | (0,7) | 7 | a
14240187 | 0 | (0,8) | 8 | a
14240187 | 0 | (0,9) | 9 | a
14240187 | 14240190 | (0,10) | 10 | a
(10 rows)

上面可以看到,id=1 的行的 xmax 值 变为 14240191。

总结

  1. xmin,xmax 都指事务ID (transaction ID)
  2. xmin记录的是当数据插入( Insert )时的事务ID
  3. xmax记录的是当行上的数据有变动(delete or update )时的事务ID,有两种情况
    • A: deleting/updating 事务未提交;
    • B: deleting/updating 事务 rollback

原创文章,作者:254126420,如若转载,请注明出处:https://blog.ytso.com/236377.html

(0)
上一篇 2022年1月24日
下一篇 2022年1月24日

相关推荐

发表回复

登录后才能评论