summaryrefslogtreecommitdiff
path: root/src/backend/utils/cache
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2015-01-07 00:10:19 +0100
committerAndres Freund <andres@anarazel.de>2015-01-07 00:24:58 +0100
commit7da1021542411130b66812e875c944c5aebf91d0 (patch)
tree9bef5b108a1bab35f05b88ab048fdfc25bd9d325 /src/backend/utils/cache
parent84911ff51dec1b66f712ee966a84c1c434e8f875 (diff)
Correctly handle relcache invalidation corner case during logical decoding.
When using a historic snapshot for logical decoding it can validly happen that a relation that's in the relcache isn't visible to that historic snapshot. E.g. if a newly created relation is referenced in the query that uses the SQL interface for logical decoding and a sinval reset occurs. The earlier commit that fixed the error handling for that corner case already improves the situation as a ERROR is better than hitting an assertion... But it's obviously not good enough. So additionally allow that case without an error if a historic snapshot is set up - that won't allow an invalid entry to stay in the cache because it's a) already marked invalid and will thus be rebuilt during the next access b) the syscaches will be reset at the end of decoding. There might be prettier solutions to handle this case, but all that we could think of so far end up being much more complex than this quite simple fix. This fixes the assertion failures reported by the buildfarm (markhor, tick, leech) after the introduction of new regression tests in 89fd41b390a4. The failure there weren't actually directly caused by CLOBBER_CACHE_ALWAYS but the extraordinary long runtimes due to it lead to sinval resets triggering the behaviour. Discussion: 22459.1418656530@sss.pgh.pa.us Backpatch to 9.4 where logical decoding was introduced.
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r--src/backend/utils/cache/relcache.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index b7cda3e1733..f6520a0222b 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -2102,6 +2102,18 @@ RelationClearRelation(Relation relation, bool rebuild)
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
* if we get here anyway, we can't just delete the relcache entry,