gpt4 book ai didi

sql - 为什么 postgres 表中的 xmax 系统列对于未删除的行不为零?

转载 作者:行者123 更新时间:2023-11-29 11:41:12 27 4
gpt4 key购买 nike

我有下表:

       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 列相关的问题:-

  1. 根据 postgres 文档,xmax 存储删除此行的事务的 ID。但是既然我的行还没有被删除,那么为什么它包含非零值。

  2. Postgres 文档说 cmin 包含事务中创建此行的语句的序列号。根据 SQL 标准,每条语句都是一个独立的事务,因此,它必须包含非零数字的 cmin 列。

请指正我错的地方。提前致谢。

最佳答案

我会先回答你的第二个问题,因为这很简单:

cmin 从零开始计数,因此 cmin 为零意味着这是事务中的第一条语句。如果您的所有交易都包含一个语句,您可以期望 cmin 始终为零。

关于xmax的含义:

除了存储删除行的事务编号外,该系统列还用于存储行锁。这些存储在行本身而不是共享内存中,以避免锁表溢出。

行锁有两种不同的存储方式:

  • 如果只有一个事务持有一行锁,则事务号存储在xmax中。

  • 如果多个事务对一行有(共享)锁,则会创建一个multixact 结构,并将其编号存储在xmax 中。

xmax的不同用法之间没有冲突,因为数据库有额外的信息:

  • 表格行中的其他标志(作为系统列不可见)消除了 xmax 的含义。

  • 提交日志 存储事务是否已提交。只有被提交的事务删除的行才真正被删除。

总而言之,如果您在 xmax 中看到一个非零值,这可能意味着四件事:

  • 该行已被删除或更新,您的查询运行时使用的快照早于修改事务。

  • 该行已被回滚的事务删除或更新。

  • 该行被锁定或在过去的某个时间点被锁定,您会看到锁定事务的事务 ID。

  • 和上面一样,但是你看到一个 multixact 值。您可以使用函数 pg_get_multixact_members 来查看哪些交易属于它。

您可能有兴趣阅读 my blog post我在这里更详细地探讨了这个问题。

关于sql - 为什么 postgres 表中的 xmax 系统列对于未删除的行不为零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49695279/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com