使用FOR UPDATE进行奇怪的清理行为

时间:2014-06-24 08:49:08

标签: sql-update postgresql-9.3 mvcc

我想知道在UPDATE操作后是否不应将xmax值设置为零,即使在子查询中使用了FOR UPDATE子句?

我创建了测试表:

CREATE TABLE def.dummy
(
  id serial NOT NULL,
  nazwa text,
  CONSTRAINT pk_dummy PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);

并插入了一些值:

INSERT INTO def.dummy(
            nazwa)
    VALUES ('1'),('2'),('3');

现在,当我尝试使用子查询进行更新时:

UPDATE def.dummy AS sp
SET nazwa = 'changed' FROM
(SELECT id, nazwa, xmax, xmin
 FROM def.dummy
          WHERE id=1
AND xmax = 0
LIMIT 1 FOR UPDATE) AS get_set
WHERE get_set.id = sp.id;
RETURNING sp.*;

提交事务后xmax值不会重置为0但保持为: xmax after update

这是正确的行为吗?如果是,为什么xmax在运行后没有设置为零?

1 个答案:

答案 0 :(得分:1)

是的,这种行为是正确的。 Xmax也用于储物柜,不仅仅是更新器,它还取决于值的读者,以确保在t_infomask中设置LOCK位时忽略非零值(参见src/include/access/htup_details.h for t_infomask中的位值。但是,您无法从常规SQL界面访问t_infomask,但请参阅pageinspect扩展程序,该扩展程序可让您访问它。

请注意,元组也可以通过外键检查锁定,因此不仅FOR UPDATE会导致非零值出现在Xmax中。