diff options
author | Noah Misch <noah@leadboat.com> | 2017-11-05 09:25:52 -0800 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2017-11-05 09:26:47 -0800 |
commit | 2a2e2e85e0f67213816126d654615413930dd8b3 (patch) | |
tree | aca731eedc84440c92a5364bbdcfc75fd4c4fb34 | |
parent | 946f165182a2e643c18fa21b563dc3ccc0c9ada7 (diff) | |
download | postgresql-2a2e2e85e0f67213816126d654615413930dd8b3.tar.gz postgresql-2a2e2e85e0f67213816126d654615413930dd8b3.zip |
Ignore CatalogSnapshot when checking COPY FREEZE prerequisites.
This restores the ability, essentially lost in commit
ffaa44cb559db332baeee7d25dedd74a61974203, to use COPY FREEZE under
REPEATABLE READ isolation. Back-patch to 9.4, like that commit.
Reviewed by Tom Lane.
Discussion: https://postgr.es/m/CA+TgmoahWDm-7fperBxzU9uZ99LPMUmEpSXLTw9TmrOgzwnORw@mail.gmail.com
-rw-r--r-- | src/backend/commands/copy.c | 18 | ||||
-rw-r--r-- | src/backend/utils/time/snapmgr.c | 8 |
2 files changed, 23 insertions, 3 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 71bec156cdb..25b1180461e 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -2167,13 +2167,25 @@ CopyFrom(CopyState cstate) /* * Optimize if new relfilenode was created in this subxact or one of its * committed children and we won't see those rows later as part of an - * earlier scan or command. This ensures that if this subtransaction - * aborts then the frozen rows won't be visible after xact cleanup. Note + * earlier scan or command. The subxact test ensures that if this subxact + * aborts then the frozen rows won't be visible after xact cleanup. Note * that the stronger test of exactly which subtransaction created it is - * crucial for correctness of this optimisation. + * crucial for correctness of this optimisation. The test for an earlier + * scan or command tolerates false negatives. FREEZE causes other sessions + * to see rows they would not see under MVCC, and a false negative merely + * spreads that anomaly to the current session. */ if (cstate->freeze) { + /* + * Tolerate one registration for the benefit of FirstXactSnapshot. + * Scan-bearing queries generally create at least two registrations, + * though relying on that is fragile, as is ignoring ActiveSnapshot. + * Clear CatalogSnapshot to avoid counting its registration. We'll + * still detect ongoing catalog scans, each of which separately + * registers the snapshot it uses. + */ + InvalidateCatalogSnapshot(); if (!ThereAreNoPriorRegisteredSnapshots() || !ThereAreNoReadyPortals()) ereport(ERROR, (ERRCODE_INVALID_TRANSACTION_STATE, diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c index a70605b0375..331c91044f2 100644 --- a/src/backend/utils/time/snapmgr.c +++ b/src/backend/utils/time/snapmgr.c @@ -1343,6 +1343,14 @@ DeleteAllExportedSnapshotFiles(void) FreeDir(s_dir); } +/* + * ThereAreNoPriorRegisteredSnapshots + * Is the registered snapshot count less than or equal to one? + * + * Don't use this to settle important decisions. While zero registrations and + * no ActiveSnapshot would confirm a certain idleness, the system makes no + * guarantees about the significance of one registered snapshot. + */ bool ThereAreNoPriorRegisteredSnapshots(void) { |