postgresql xmin xmax cmin cmax ctid

它们是 PostgreSQL 中最常被查询的五个系统列。它们都是隐式定义的(无需手动声明),始终存在(除了 tableoid 在某些分区情况下),并且 不会SELECT * 返回 ------ 必须显式指定列名。

它们实现了 MVCC(多版本并发控制)、行版本管理、可见性规则和物理行寻址。

快速汇总表

列名 类型 大小 用途 / 含义 典型值 / 备注
xmin xid 4 字节 创建/插入此版本行的事务 ID 行的"诞生"事务。对于大多数快照,其可见性始于该事务提交之时。MVCC 的核心。
xmax xid 4 字节 删除/更新(使失效)此行版本的事务 ID 0 = 行仍存活(尚未被删除或更新)。非 0 = 行已死或被 UPDATE 取代(新版本已存在)。可能暂时持有多事务锁 ID。
cmin cid 4 字节 在插入事务内的命令 ID 事务内的哪个语句/命令创建了这个版本。对于简单事务通常为 0。用于 事务内部可见性
cmax cid 4 字节 在删除事务内的命令 ID,如果未删除则为 0 事务内的哪个语句使此行失效。对存活的行则为 0。cmin/cmax 在元组头中共用同一个存储槽位(重叠)。
ctid tid 6 字节 此行版本的物理位置:(块号, 块内元组索引) "行指针"。UPDATE 或 VACUUM FULL 时会改变。用于 HOT 链(在同一页面上指向新版本的前向指针)。可用作物理定位器(但不稳定)。

可见性规则(MVCC 的核心)

PostgreSQL 根据 快照 结合这些字段,决定一个行版本对你的 事务 是否可见:

行版本可见的条件(简化版,基于"读已提交"/"可重复读"规则):

  1. xmin 已提交 xmin ≤ 快照的水平线

  2. 并且
    xmax = 0
    xmax 正在进行中
    xmax > 快照的水平线
    xmax 已中止/回滚

事务内部可见性 (同一事务能看到自身的更改)还会用到 cmin/cmax 和命令序列。

  • 读已提交 级别:每个语句获取新快照 → 能在事务中途看到其他并发提交的更改。

  • 可重复读 / 可序列化 级别:在第一个语句处获取快照 → 在整个事务期间保持稳定的视图。

实践示例

复制代码
-- 查看它们(它们对 SELECT * 隐藏)
SELECT xmin, xmax, cmin, cmax, ctid, * FROM mytable WHERE id = 42;

-- 典型的存活行(刚插入,尚未更新/删除)
xmin | xmax | cmin | cmax | ctid
-----+------+------+------+---------
 742 |    0 |    0 |    0 | (123,7)

-- 执行 UPDATE 后的行(旧版本,xmax 被更新事务设置)
xmin | xmax | cmin | cmax | ctid
-----+------+------+------+---------
 742 |  745 |    0 |    1 | (123,7)   ← 旧版本,xmax = 745

-- UPDATE 创建的新版本
xmin | xmax | cmin | cmax | ctid
-----+------+------+------+---------
 745 |    0 |    1 |    0 | (124,3)   ← 新版本,ctid 通常不同

重要行为

  • UPDATE → 创建新的行版本(新的 xminctid 通常改变);旧版本被设置 xmax → 更新者提交后变为死行。

  • HOT UPDATE(堆内元组) → 更新发生在同一页面,索引不变 → 旧的 ctid 更新为指向新位置 → 避免索引膨胀。

  • DELETE → 设置 xmax,不会创建新版本。

  • VACUUM → 清理死行版本(即 xmax 已提交且小于最老运行事务的行)。

  • ctid 不稳定 ------ 切勿将其用作永久标识符(请用主键)。可用于调试重复行、追踪 HOT 链或底层页面检查。

底层访问(pageinspect 扩展)

复制代码
CREATE EXTENSION pageinspect;

-- 查看原始元组头字段 (t_xmin ≈ xmin, 等)
SELECT lp, t_xmin AS xmin, t_xmax AS xmax, t_cid AS cid, t_ctid AS ctid
FROM heap_page_items(get_raw_page('mytable', 0));

总结

  • xmin / xmax → 行的诞生与消亡(MVCC 的核心机制)

  • cmin / cmax → 多语句事务内部命令的先后顺序(除深度调试外很少需要)

  • ctid → 物理位置(经常变化,对内部机制分析和取证有用)

正是这些字段,使得 PostgreSQL 能够在 不加读锁 的情况下提供出色的并发能力 ------ 每个事务都能看到自己的一致数据版本。

相关推荐
是桃萌萌鸭~6 小时前
oracle 排查卡顿相关日志
数据库·oracle
昨夜见军贴06166 小时前
合规性管理的现代化实践:IACheck的AI审核如何系统提升生产型检测报告的合规水平
大数据·运维·人工智能
wuxi_joe6 小时前
一家研发制造企业的“软件进化史”
大数据·数据库·制造
Lansonli6 小时前
大数据Spark(七十九):Action行动算子countByKey和countByValue使用案例
大数据·分布式·spark
草莓熊Lotso6 小时前
远程控制软件实测!2026年1月远程软件从“夯”到“拉”全功能横评
运维·服务器·数据库·人工智能
发哥来了6 小时前
主流AI视频生成模型商用化能力评测:三大核心维度对比分析
大数据·人工智能·音视频
冰暮流星6 小时前
sql之删除与软删除
数据库·sql
沐雪架构师6 小时前
LangChain 1.0 记忆管理:短期与长期记忆详解
服务器·数据库·langchain
Hello.Reader6 小时前
Flink CLI 从提交作业到 Savepoint/Checkpoint、再到 YARN/K8S 与 PyFlink
大数据·flink·kubernetes