72000 — snapshot_too_old
72000
速览
72000 是历史 snapshot_too_old 错误。PostgreSQL 16.15 仍定义并发出它;该 SQLSTATE 在 PostgreSQL 17 大版本移除。因此 16.15 是最后一个大版本线中的后续小版本快照,不是移除点。
| 字段 | 值 |
|---|---|
| SQLSTATE | 72000 |
| 条件名 | snapshot_too_old |
| 状态 | 已移除 |
| 已知存在于 | 9.6.0 |
| 锁定快照 | 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15 |
| 宏 | ERRCODE_SNAPSHOT_TOO_OLD |
| 别名 | — |
含义
固定的 16.15 源码中,old_snapshot_threshold 是 PGC_POSTMASTER 整数 GUC,-1 关闭功能。TestForOldSnapshot 内联 guard 要求阈值非负、快照为 MVCC 或 TOAST 且 LSN 有效,并且页面 LSN 晚于快照;随后调用 TestForOldSnapshot_impl,它还要求关系是允许提前清理的永久、非系统目录关系,并比较 snapshot.whenTaken 与 GetOldSnapshotThresholdTimestamp()。快照太旧时发出 ERROR 72000,主消息为 snapshot too old。
阈值时间戳由旧快照的时间到 XID 映射维护,供提前清理和 vacuum 使用。PG16.15 文档说明阈值之前已死数据可以被 vacuum,读取在快照建立后修改过的页面可能失败;物化游标或系统目录可能不触发错误。为检测条件而保留的关系空间不会直接归还 OS,除非显式执行 VACUUM FULL 等操作。
消息
- ERROR,SQLSTATE
72000:snapshot too old。
锁定目录在 PG17/18 没有当前定义行。不要推断替代 SQLSTATE,也不要把无关的当前错误声称为等价物。
诊断
在 PostgreSQL 9.6–16 上记录大版本、SHOW old_snapshot_threshold、事务快照年龄、关系类型、页面读取路径以及 vacuum/提前清理历史。检查关系是否被 guard 排除(例如系统目录)、读取是否使用物化游标或结果集,以及设置是否在服务器启动时生效。源码核验不能建立实际集群的阈值或清理历史。
处理
这是语句级 ERROR;显式事务中继续发 SQL 前先回滚整个事务,或回到已经建立的保存点。旧快照无法原地修复:结束或缩短长期读取事务,按历史大版本设置合适的启动配置(GUC 为 PGC_POSTMASTER,修改需重启),再以幂等边界重跑整个读取单元。PG17 及以后应先确认当前错误和机制,不要仅凭历史名称安装 72000 handler。
版本
锁定定义文件记录 72000 从 9.6.0 到 16.15,PG17/18 无定义。16.15 源码提供 GUC 与 guard;固定缓冲区管理器发出路径来自 commit 7d3e000c5961a544302072058a1184e9a588837b。目录边界说明它在 PG17 大版本线移除,而不是在 16.15 小版本移除。
相关
来源
src/backend/storage/buffer/bufmgr.c#L5663-L5675
src/include/storage/bufmgr.h#L363-L392
src/backend/utils/time/snapmgr.c#L1697-L1714
src/backend/utils/misc/guc_tables.c#L3295-L3302
doc/src/sgml/config.sgml#L2827-L2884
结构化证据记录保存历史定义、guard、GUC、文档和源码/运行边界。