72000 — snapshot_too_old
72000
At a glance
72000 is a historical snapshot_too_old error. PostgreSQL 16.15 still defines and emits it; the SQLSTATE was removed in the PostgreSQL 17 major line. PostgreSQL 16.15 is therefore a later minor snapshot of the last major line, not the removal point.
| Field | Value |
|---|---|
| SQLSTATE | 72000 |
| Condition | snapshot_too_old |
| Status | removed |
| Known present by | 9.6.0 |
| Locked snapshots | 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15 |
| Macros | ERRCODE_SNAPSHOT_TOO_OLD |
| Aliases | — |
Meaning
In the fixed 16.15 sources, old_snapshot_threshold is a PGC_POSTMASTER integer GUC; -1 disables the feature. The inline TestForOldSnapshot guard requires a non-negative threshold, an MVCC or TOAST snapshot with a valid LSN, and a page LSN newer than the snapshot. It then calls TestForOldSnapshot_impl, which additionally requires a permanent, non-catalog relation that allows early pruning and compares snapshot.whenTaken with GetOldSnapshotThresholdTimestamp(). If the snapshot is too old, the function raises ERROR 72000 with snapshot too old.
The threshold timestamp is maintained by the old-snapshot time-to-XID mapping used by early pruning and vacuum. The PG16.15 documentation says that dead data older than the threshold may be vacuumed, and a read of a page modified after the snapshot can fail; a materialized cursor or a system catalog may avoid the error. Space retained for detection is not released to the operating system until an explicit operation such as VACUUM FULL.
Messages
- ERROR, SQLSTATE
72000:snapshot too old.
There is no current PG17/18 definition row in the locked catalogue. Do not infer a replacement SQLSTATE or claim that an unrelated current error is equivalent.
Diagnosis
On PostgreSQL 9.6 through 16, record the major version, SHOW old_snapshot_threshold, transaction snapshot age, relation kind, page/read path, and vacuum or pruning history. Check whether the relation is excluded by the guard (for example a system catalog), whether the read used a materialized cursor or result set, and whether the setting was active at server start. A source-only review cannot establish the threshold or cleanup history on a live cluster.
Response
This is a statement ERROR; in an explicit transaction, roll back the transaction or to an already-established savepoint before issuing more SQL. The old snapshot cannot be repaired in place: end or shorten the long-running reader, use a suitable startup configuration for the historical major (the GUC is PGC_POSTMASTER, so changing it requires restart), and rerun the whole read unit with an idempotent boundary. On PostgreSQL 17 and later, first identify the current error and mechanism instead of installing a 72000 handler based on the historical name.
Versions
The locked definition artifact records 72000 from 9.6.0 through 16.15 and no PG17/18 definition. The 16.15 source documents the GUC and guard; the fixed buffer-manager emitter is from commit 7d3e000c5961a544302072058a1184e9a588837b. The catalogue boundary establishes removal in the PG17 major line, not in minor release 16.15.
Related
Sources
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
The structured evidence record records the historical definition, guard, GUC, documentation, and source/runtime boundary.