我有下表:
Table "public.product"
Column | Type | Modifiers
--------+---------+------------------------------------------------------
id | integer | not null default nextval('product_id_seq'::regclass)
name | text | not null
Indexes:
"product_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "stock" CONSTRAINT "stock_product_id_fkey" FOREIGN KEY (product_id) REFERENCES product(id)
此表有2条记录:-
postgres=# select xmin, xmax, cmin, cmax, * from product;
xmin | xmax | cmin | cmax | id | name
---------+---------+------+------+----+---------
3126848 | 3126856 | 0 | 0 | 1 | Parle-G
3126849 | 3126858 | 0 | 0 | 2 | Pepsi
(2 rows)
我有以下有关xmax和cmin列的问题:-
根据postgres docs,xmax存储事务的id,该id删除了此行。但由于我的行尚未删除,那么为什么它包含非零值。
Postgres docs说,cmin包含事务中语句的序列号,该语句创建了此行。根据SQL标准,每个语句本身都是一个事务,因此,对于cmin列,它必须包含非零的数字。
请纠正我的错误。提前谢谢。
最佳答案
我先回答你的第二个问题,因为这很简单:cmin
从零开始计数,因此零的cmin
表示这是事务中的第一条语句。如果您的所有事务都由一个语句组成,则可以期望cmin
始终为零。
关于xmax
的含义:
除了存储删除行的事务数外,此系统列还用于存储行锁。它们存储在行本身而不是共享内存中,以避免锁表溢出。
行锁以两种不同的方式存储:
如果只有一个事务持有一行的锁,则事务编号存储在xmax
中。
如果多个事务在一行上有一个(共享)锁,则会创建一个multixact结构,其编号存储在xmax
中。
不同的xmax
用法之间没有冲突,因为数据库有其他信息:
表行中的其他标志(作为系统列不可见)消除了xmax
的含义。
提交日志存储事务是否已提交。只有被提交的事务删除的行才真正被删除。
总而言之,如果您在xmax
中看到一个非零值,这可能意味着四件事:
该行已被删除或更新,并且您的查询正在使用早于修改事务的快照运行。
该行已被回滚的事务删除或更新。
该行被锁定或在过去的某个时间点被锁定,您将看到锁定事务的事务ID。
像上面一样,但是您看到了一个multixact值。您可以使用函数pg_get_multixact_members
查看哪些事务属于它。
你可能会对阅读感兴趣,在这里我会更详细地探讨这个问题。