Skip to content

Commit 1d377f2

Browse files
committed
Ensure snapshot is registered within ScanPgRelation().
In 9.4 I added support to use a historical snapshot in ScanPgRelation(), while adding logical decoding. Unfortunately a conflict with the concurrent removal of SnapshotNow was incorrectly resolved, leading to an unregistered snapshot being used. It is not correct to use an unregistered (or non-active) snapshot for anything non-trivial, because catalog invalidations can cause the snapshot to be invalidated. Luckily it seems unlikely to actively cause problems in practice, as ScanPgRelation() requires that we already have a lock on the relation, we only look for a single row, and we don't appear to rely on the result's tid to be correct. It however is clearly wrong and potential negative consequences would likely be hard to find. So it seems worth backpatching the fix, even without a concrete hazard. Discussion: https://postgr.es/m/20200229052459.wzhqnbhrriezg4v2@alap3.anarazel.de Backpatch: 9.5-
1 parent a54a873 commit 1d377f2

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

src/backend/utils/cache/relcache.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic)
320320
Relation pg_class_desc;
321321
SysScanDesc pg_class_scan;
322322
ScanKeyData key[1];
323-
Snapshot snapshot;
323+
Snapshot snapshot = NULL;
324324

325325
/*
326326
* If something goes wrong during backend startup, we might find ourselves
@@ -350,12 +350,12 @@ ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic)
350350
/*
351351
* The caller might need a tuple that's newer than the one the historic
352352
* snapshot; currently the only case requiring to do so is looking up the
353-
* relfilenode of non mapped system relations during decoding.
353+
* relfilenode of non mapped system relations during decoding. That
354+
* snapshot cant't change in the midst of a relcache build, so there's no
355+
* need to register the snapshot.
354356
*/
355357
if (force_non_historic)
356358
snapshot = GetNonHistoricCatalogSnapshot(RelationRelationId);
357-
else
358-
snapshot = GetCatalogSnapshot(RelationRelationId);
359359

360360
pg_class_scan = systable_beginscan(pg_class_desc, ClassOidIndexId,
361361
indexOK && criticalRelcachesBuilt,

0 commit comments

Comments
 (0)