aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2017-11-05 09:25:52 -0800
committerNoah Misch <noah@leadboat.com>2017-11-05 09:26:43 -0800
commit7932891ab9ccfa5003a8dce9af0bea60427469b3 (patch)
treeb8303fc7460e4c9989799f03352c65acf6919446 /src
parentcf0612aa2c8fdc54bb98a13ef839f43cef5eadc5 (diff)
downloadpostgresql-7932891ab9ccfa5003a8dce9af0bea60427469b3.tar.gz
postgresql-7932891ab9ccfa5003a8dce9af0bea60427469b3.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
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/copy.c18
-rw-r--r--src/backend/utils/time/snapmgr.c8
2 files changed, 23 insertions, 3 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 808ea09eeb2..7606121ee65 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -2317,13 +2317,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(ERRCODE_INVALID_TRANSACTION_STATE),
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index f68a15b90b6..9029fd0ed3b 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -1447,6 +1447,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)
{