Skip to content

Commit 1cac62d

Browse files
committed
Ignore CatalogSnapshot when checking COPY FREEZE prerequisites.
This restores the ability, essentially lost in commit ffaa44c, 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
1 parent bd8e2b3 commit 1cac62d

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

src/backend/commands/copy.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,13 +2353,25 @@ CopyFrom(CopyState cstate)
23532353
/*
23542354
* Optimize if new relfilenode was created in this subxact or one of its
23552355
* committed children and we won't see those rows later as part of an
2356-
* earlier scan or command. This ensures that if this subtransaction
2357-
* aborts then the frozen rows won't be visible after xact cleanup. Note
2356+
* earlier scan or command. The subxact test ensures that if this subxact
2357+
* aborts then the frozen rows won't be visible after xact cleanup. Note
23582358
* that the stronger test of exactly which subtransaction created it is
2359-
* crucial for correctness of this optimisation.
2359+
* crucial for correctness of this optimisation. The test for an earlier
2360+
* scan or command tolerates false negatives. FREEZE causes other sessions
2361+
* to see rows they would not see under MVCC, and a false negative merely
2362+
* spreads that anomaly to the current session.
23602363
*/
23612364
if (cstate->freeze)
23622365
{
2366+
/*
2367+
* Tolerate one registration for the benefit of FirstXactSnapshot.
2368+
* Scan-bearing queries generally create at least two registrations,
2369+
* though relying on that is fragile, as is ignoring ActiveSnapshot.
2370+
* Clear CatalogSnapshot to avoid counting its registration. We'll
2371+
* still detect ongoing catalog scans, each of which separately
2372+
* registers the snapshot it uses.
2373+
*/
2374+
InvalidateCatalogSnapshot();
23632375
if (!ThereAreNoPriorRegisteredSnapshots() || !ThereAreNoReadyPortals())
23642376
ereport(ERROR,
23652377
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),

src/backend/utils/time/snapmgr.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,14 @@ DeleteAllExportedSnapshotFiles(void)
15991599
FreeDir(s_dir);
16001600
}
16011601

1602+
/*
1603+
* ThereAreNoPriorRegisteredSnapshots
1604+
* Is the registered snapshot count less than or equal to one?
1605+
*
1606+
* Don't use this to settle important decisions. While zero registrations and
1607+
* no ActiveSnapshot would confirm a certain idleness, the system makes no
1608+
* guarantees about the significance of one registered snapshot.
1609+
*/
16021610
bool
16031611
ThereAreNoPriorRegisteredSnapshots(void)
16041612
{

0 commit comments

Comments
 (0)