diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 1ebb37faa929d8e37d44b08e350c18482698eb1f..24c92e791ff99b57927f918b96ddba4648ec9be7 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -2192,6 +2192,18 @@ RelationClearRelation(Relation relation, bool rebuild) newrel = RelationBuildDesc(save_relid, false); if (newrel == NULL) { + /* + * We can validly get here, if we're using a historic snapshot in + * which a relation, accessed from outside logical decoding, is + * still invisible. In that case it's fine to just mark the + * relation as invalid and return - it'll fully get reloaded by + * the cache reset at the end of logical decoding (or at the next + * access). During normal processing we don't want to ignore this + * case as it shouldn't happen there, as explained below. + */ + if (HistoricSnapshotActive()) + return; + /* * This shouldn't happen as dropping a relation is intended to be * impossible if still referenced (c.f. CheckTableNotInUse()). But