@@ -2167,13 +2167,25 @@ CopyFrom(CopyState cstate)
2167
2167
/*
2168
2168
* Optimize if new relfilenode was created in this subxact or one of its
2169
2169
* committed children and we won't see those rows later as part of an
2170
- * earlier scan or command. This ensures that if this subtransaction
2171
- * aborts then the frozen rows won't be visible after xact cleanup. Note
2170
+ * earlier scan or command. The subxact test ensures that if this subxact
2171
+ * aborts then the frozen rows won't be visible after xact cleanup. Note
2172
2172
* that the stronger test of exactly which subtransaction created it is
2173
- * crucial for correctness of this optimisation.
2173
+ * crucial for correctness of this optimisation. The test for an earlier
2174
+ * scan or command tolerates false negatives. FREEZE causes other sessions
2175
+ * to see rows they would not see under MVCC, and a false negative merely
2176
+ * spreads that anomaly to the current session.
2174
2177
*/
2175
2178
if (cstate -> freeze )
2176
2179
{
2180
+ /*
2181
+ * Tolerate one registration for the benefit of FirstXactSnapshot.
2182
+ * Scan-bearing queries generally create at least two registrations,
2183
+ * though relying on that is fragile, as is ignoring ActiveSnapshot.
2184
+ * Clear CatalogSnapshot to avoid counting its registration. We'll
2185
+ * still detect ongoing catalog scans, each of which separately
2186
+ * registers the snapshot it uses.
2187
+ */
2188
+ InvalidateCatalogSnapshot ();
2177
2189
if (!ThereAreNoPriorRegisteredSnapshots () || !ThereAreNoReadyPortals ())
2178
2190
ereport (ERROR ,
2179
2191
(ERRCODE_INVALID_TRANSACTION_STATE ,
0 commit comments