Commit 7da83415 authored by Noah Misch's avatar Noah Misch

Revive "snapshot too old" with wal_level=minimal and SET TABLESPACE.

Given a permanent relation rewritten in the current transaction, the
old_snapshot_threshold mechanism assumed the relation had never been
subject to early pruning.  Hence, a query could fail to report "snapshot
too old" when the rewrite followed an early truncation.  ALTER TABLE SET
TABLESPACE is probably the only rewrite mechanism capable of exposing
this bug.  REINDEX sets indcheckxmin, avoiding the problem.  CLUSTER has
zeroed page LSNs since before old_snapshot_threshold existed, so
old_snapshot_threshold has never cooperated with it.  ALTER TABLE
... SET DATA TYPE makes the table look empty to every past snapshot,
which is strictly worse.  Back-patch to v13, where commit
c6b92041 broke this.

Kyotaro Horiguchi and Noah Misch

Discussion: https://postgr.es/m/20210113.160705.2225256954956139776.horikyota.ntt@gmail.com
parent 360bd232
......@@ -1764,7 +1764,11 @@ TransactionIdLimitedForOldSnapshots(TransactionId recentXmin,
Assert(OldSnapshotThresholdActive());
Assert(limit_ts != NULL && limit_xid != NULL);
if (!RelationAllowsEarlyPruning(relation))
/*
* TestForOldSnapshot() assumes early pruning advances the page LSN, so we
* can't prune early when skipping WAL.
*/
if (!RelationAllowsEarlyPruning(relation) || !RelationNeedsWAL(relation))
return false;
ts = GetSnapshotCurrentTimestamp();
......
......@@ -37,7 +37,7 @@
*/
#define RelationAllowsEarlyPruning(rel) \
( \
RelationNeedsWAL(rel) \
(rel)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT \
&& !IsCatalogRelation(rel) \
&& !RelationIsAccessibleInLogicalDecoding(rel) \
)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment