Skip to content

Commit 2776922

Browse files
committed
Assert in init_toast_snapshot() that some snapshot registered or active.
Commit <FIXME> fixed the bug that RemoveTempRelationsCallback() did not push/register a snapshot. That only went unnoticed because often a valid catalog snapshot exists and is returned by GetOldestSnapshot(). But due to invalidation processing that is not reliable. Thus assert in init_toast_snapshot() that there is a registered or active snapshot, using the new HaveRegisteredOrActiveSnapshot(). Author: Andres Freund Discussion: https://postgr.es/m/20220219180002.6tubjq7iw7m52bgd@alap3.anarazel.de
1 parent 7c38ef2 commit 2776922

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

src/backend/access/common/toast_internals.c

+9
Original file line numberDiff line numberDiff line change
@@ -660,5 +660,14 @@ init_toast_snapshot(Snapshot toast_snapshot)
660660
if (snapshot == NULL)
661661
elog(ERROR, "cannot fetch toast data without an active snapshot");
662662

663+
/*
664+
* Catalog snapshots can be returned by GetOldestSnapshot() even if not
665+
* registered or active. That easily hides bugs around not having a
666+
* snapshot set up - most of the time there is a valid catalog
667+
* snapshot. So additionally insist that the current snapshot is
668+
* registered or active.
669+
*/
670+
Assert(HaveRegisteredOrActiveSnapshot());
671+
663672
InitToastSnapshot(*toast_snapshot, snapshot->lsn, snapshot->whenTaken);
664673
}

src/backend/utils/time/snapmgr.c

+26
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,32 @@ ThereAreNoPriorRegisteredSnapshots(void)
16251625
return false;
16261626
}
16271627

1628+
/*
1629+
* HaveRegisteredOrActiveSnapshots
1630+
* Is there any registered or active snapshot?
1631+
*
1632+
* NB: Unless pushed or active, the cached catalog snapshot will not cause
1633+
* this function to return true. That allows this function to be used in
1634+
* checks enforcing a longer-lived snapshot.
1635+
*/
1636+
bool
1637+
HaveRegisteredOrActiveSnapshot(void)
1638+
{
1639+
if (ActiveSnapshot != NULL)
1640+
return true;
1641+
1642+
/*
1643+
* The catalog snapshot is in RegisteredSnapshots when valid, but can be
1644+
* removed at any time due to invalidation processing. If explicitly
1645+
* registered more than one snapshot has to be in RegisteredSnapshots.
1646+
*/
1647+
if (pairingheap_is_empty(&RegisteredSnapshots) ||
1648+
!pairingheap_is_singular(&RegisteredSnapshots))
1649+
return false;
1650+
1651+
return CatalogSnapshot == NULL;
1652+
}
1653+
16281654

16291655
/*
16301656
* Return a timestamp that is exactly on a minute boundary.

src/include/utils/snapmgr.h

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ extern bool XactHasExportedSnapshots(void);
135135
extern void DeleteAllExportedSnapshotFiles(void);
136136
extern void WaitForOlderSnapshots(TransactionId limitXmin, bool progress);
137137
extern bool ThereAreNoPriorRegisteredSnapshots(void);
138+
extern bool HaveRegisteredOrActiveSnapshot(void);
138139
extern bool TransactionIdLimitedForOldSnapshots(TransactionId recentXmin,
139140
Relation relation,
140141
TransactionId *limit_xid,

0 commit comments

Comments
 (0)