Re: ATTACH/DETACH PARTITION CONCURRENTLY

David Rowley <david.rowley@2ndquadrant.com>

From: David Rowley <david.rowley@2ndquadrant.com>
To: Robert Haas <robertmhaas@gmail.com>
Cc: Andres Freund <andres@anarazel.de>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>, Simon Riggs <simon@2ndquadrant.com>
Date: 2018-11-08T00:06:52Z
Lists: pgsql-hackers
On 8 November 2018 at 05:05, Robert Haas <robertmhaas@gmail.com> wrote:
> That seems OK at present, because no new partitions can have appeared
> since ExecSetupPartitionTupleRouting() acquired locks.  But if we
> allow new partitions to be added with only ShareUpdateExclusiveLock,
> then I think there would be a problem.  If a new partition OID creeps
> into the partition descriptor after find_all_inheritors() and before
> we fetch its partition descriptor, then we wouldn't have previously
> taken a lock on it and would still be attempting to open it without a
> lock, which is bad (cf. b04aeb0a053e7cf7faad89f7d47844d8ba0dc839).
>
> Admittedly, it might be a bit hard to provoke a failure here because
> I'm not exactly sure how you could trigger a relcache reload in the
> critical window, but I don't think we should rely on that.
>
> More generally, it seems a bit strange that we take the approach of
> locking the entire partitioning hierarchy here regardless of which
> relations the query actually knows about.  If some relations have been
> pruned, presumably we don't need to lock them; if/when we permit
> concurrent partition, we don't need to lock any new ones that have
> materialized.  We're just going to end up ignoring them anyway because
> there's nothing to do with the information that they are or are not
> excluded from the query when they don't appear in the query plan in
> the first place.

While the find_all_inheritors() call is something I'd like to see
gone, I assume it was done that way since an UPDATE might route a
tuple to a partition that there is no subplan for and due to INSERT
with VALUES not having any RangeTblEntry for any of the partitions.
Simply, any partition which is a descendant of the target partition
table could receive the tuple regardless of what might have been
pruned.

-- 
 David Rowley                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services


Commits

  1. Allow ATTACH PARTITION with only ShareUpdateExclusiveLock.

  2. Change lock acquisition order in expand_inherited_rtentry.

  3. Move code for managing PartitionDescs into a new file, partdesc.c

  4. Remove more redundant relation locking during executor startup.

  5. Add assertions that we hold some relevant lock during relation open.

  6. Try to acquire relation locks in RangeVarGetRelid.