Postgres 9.5:作为外键引用的行的非零 xmax
Postgres 9.5: Non-zero xmax of a row refenced as a foreign key
根据http://www.postgresql.org/docs/current/static/ddl-system-columns.html:
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't committed yet, or that an attempted
deletion was rolled back.
但是如果一行被另一行作为外键引用,它也有一个非零的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 如何知道该行仍然存在?
MVCC, unveiling xmin and xmax work (slides 上有 Bruce Momkian 的演讲,搜索 "Row Locks Using Xmax")。
长话短说:xmax
也用于行锁(文档中未详细介绍),在这种特定情况下,xmax
用于确保其他事务不会修改引用的元组(因此 CASCADE
将等待,例如),除非 txid_current()
大于插入的 xmax
。实际上,table 中的那些非零 xmax 没有用,并被 VACUUM FULL demo
清除。
根据http://www.postgresql.org/docs/current/static/ddl-system-columns.html:
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't committed yet, or that an attempted deletion was rolled back.
但是如果一行被另一行作为外键引用,它也有一个非零的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 如何知道该行仍然存在?
MVCC, unveiling xmin and xmax work (slides 上有 Bruce Momkian 的演讲,搜索 "Row Locks Using Xmax")。
长话短说:xmax
也用于行锁(文档中未详细介绍),在这种特定情况下,xmax
用于确保其他事务不会修改引用的元组(因此 CASCADE
将等待,例如),除非 txid_current()
大于插入的 xmax
。实际上,table 中的那些非零 xmax 没有用,并被 VACUUM FULL demo
清除。