Re: ATTACH/DETACH PARTITION CONCURRENTLY
Alvaro Herrera <alvherre@2ndquadrant.com>
From: Alvaro Herrera <alvherre@2ndquadrant.com>
To: Robert Haas <robertmhaas@gmail.com>
Cc: David Rowley <david.rowley@2ndquadrant.com>, Andres Freund <andres@anarazel.de>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>, Simon Riggs <simon@2ndquadrant.com>
Date: 2018-08-20T20:21:22Z
Lists: pgsql-hackers
On 2018-Aug-13, Robert Haas wrote: > I think this is a somewhat confused analysis. We don't use > SnapshotAny for catalog scans, and we never have. We used to use > SnapshotNow, and we now use a current MVCC snapshot. What you're > talking about, I think, is possibly using the transaction snapshot > rather than a current MVCC snapshot for the catalog scans. > > I've thought about similar things, but I think there's a pretty deep > can of worms. For instance, if you built a relcache entry using the > transaction snapshot, you might end up building a seemingly-valid > relcache entry for a relation that has been dropped or rewritten. > When you try to access the relation data, you'll be attempt to access > a relfilenode that's not there any more. Similarly, if you use an > older snapshot to build a partition descriptor, you might thing that > relation OID 12345 is still a partition of that table when in fact > it's been detached - and, maybe, altered in other ways, such as > changing column types. I wonder if this all stems from a misunderstanding of what I suggested to David offlist. My suggestion was that the catalog scans would continue to use the catalog MVCC snapshot, and that the relcache entries would contain all the partitions that appear to the catalog; but each partition's entry would carry the Xid of the creating transaction in a field (say xpart), and that field is compared to the regular transaction snapshot: if xpart is visible to the transaction snapshot, then the partition is visible, otherwise not. So you never try to access a partition that doesn't exist, because those just don't appear at all in the relcache entry. But if you have an old transaction running with an old snapshot, and the partitioned table just acquired a new partition, then whether the partition will be returned as part of the partition descriptor or not depends on the visibility of its entry. I think that works fine for ATTACH without any further changes. I'm not so sure about DETACH, particularly when snapshots persist for a "long time" (a repeatable-read transaction). ISTM that in the above design, the partition descriptor would lose the entry for the detached partition ahead of time, which means queries would silently fail to see their data (though they wouldn't crash). I first thought this could be fixed by waiting for those snapshots to finish, but then I realized that there's no actual place where waiting achieves anything. Certainly it's not useful to wait before commit (because other snapshots are going to be starting all the time), and it's not useful to start after the commit (because by then the catalog tuple is already gone). Maybe we need two transactions: mark partition as removed with an xmax of sorts, commit, wait for all snapshots, start transaction, remove partition catalog tuple, commit. -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Commits
-
Allow ATTACH PARTITION with only ShareUpdateExclusiveLock.
- 898e5e3290a7 12.0 landed
-
Change lock acquisition order in expand_inherited_rtentry.
- f4b6341d5fcb 12.0 landed
-
Move code for managing PartitionDescs into a new file, partdesc.c
- 1bb5e7821810 12.0 landed
-
Remove more redundant relation locking during executor startup.
- f2343653f5b2 12.0 cited
-
Add assertions that we hold some relevant lock during relation open.
- b04aeb0a053e 12.0 cited
-
Try to acquire relation locks in RangeVarGetRelid.
- 4240e429d0c2 9.2.0 cited