aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2020-03-28 11:52:11 -0700
committerAndres Freund <andres@anarazel.de>2020-03-28 12:04:44 -0700
commit1d377f203ea47483d48b041c32986dda2f672205 (patch)
treecebbe729a94ba6a0312b680aebe9ad57ab22ea64 /src
parenta54a87320782e775794f2f0b05fcd0c1fc5539d0 (diff)
downloadpostgresql-1d377f203ea47483d48b041c32986dda2f672205.tar.gz
postgresql-1d377f203ea47483d48b041c32986dda2f672205.zip
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-
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/cache/relcache.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 019fa92404b..d0ad738c240 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -320,7 +320,7 @@ ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic)
Relation pg_class_desc;
SysScanDesc pg_class_scan;
ScanKeyData key[1];
- Snapshot snapshot;
+ Snapshot snapshot = NULL;
/*
* If something goes wrong during backend startup, we might find ourselves
@@ -350,12 +350,12 @@ ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic)
/*
* The caller might need a tuple that's newer than the one the historic
* snapshot; currently the only case requiring to do so is looking up the
- * relfilenode of non mapped system relations during decoding.
+ * relfilenode of non mapped system relations during decoding. That
+ * snapshot cant't change in the midst of a relcache build, so there's no
+ * need to register the snapshot.
*/
if (force_non_historic)
snapshot = GetNonHistoricCatalogSnapshot(RelationRelationId);
- else
- snapshot = GetCatalogSnapshot(RelationRelationId);
pg_class_scan = systable_beginscan(pg_class_desc, ClassOidIndexId,
indexOK && criticalRelcachesBuilt,