根据http://www.postgresql.org/docs/current/static/ddl-system-columns.html:
xmax - 删除事务的标识(事务ID),或 对于未删除的行版本为零。这个专栏可以 在可见的行版本中非零。那通常表明了 删除尚未提交的交易或已尝试的交易 删除被回滚。
但是如果一行被另一行引用为外键,则xmax也具有非零值:
drop table if exists demo;
create table demo
(
id bigint primary key not null,
pid bigint,
constraint demo_pid_fk
foreign key (pid)
references demo (id)
);
insert into demo(id, pid) values(1, NULL);
insert into demo(id, pid) values(2, 1);
insert into demo(id, pid) values(3, 3);
select xmin, xmax, * from demo;
xmin | xmax | id | pid
------+------+----+-----
1074 | 1075 | 1 |
1075 | 0 | 2 | 1
1076 | 1076 | 3 | 3
(3 rows)
insert into demo(id, pid) values(4, 1);
select xmin, xmax, * from demo;
xmin | xmax | id | pid
------+------+----+-----
1074 | 1077 | 1 |
1075 | 0 | 2 | 1
1076 | 1076 | 3 | 3
1077 | 0 | 4 | 1
(4 rows)
在上面的示例中,似乎xmax设置为将该行作为外键引用的最后一个事务的id。为什么会这样? Postgres如何知道该行仍然存在?
答案 0 :(得分:2)
Bruce Momkian在MVCC, unveiling xmin and xmax work(slides上进行了一次演讲,使用Xmax和#34搜索"行锁;)。
长话短说:xmax
也用于 - 在文档中没有很好地涵盖 - 用于行锁,在这种特定情况下CASCADE
用于确保其他事务远离修改引用的元组(所以txid_current()
会等待(例如),除非xmax
大于插入的VACUUM FULL demo
。实际上,表格中的非零xmax不会被{{1}}使用和清理。