Обсуждение: Allowing multiple DDL commands to run simultaneously

Поиск
Список
Период
Сортировка

Allowing multiple DDL commands to run simultaneously

От
Simon Riggs
Дата:
We use the word CONCURRENTLY to describe DDL that executes without
preventing select, insert, update or delete against a table. That is
not the topic discussed here.

I've been asked if we could consider allowing more types of DDL to run
at the same time as each other. Specifically, that all/most of the DDL
commands that currently take ShareUpdateExclusive lock should be able
to run side-by-side with each other, i.e. any of the following could
run together

VACUUM (without FULL), ANALYZE, CREATE/DROP INDEX CONCURRENTLY, CREATE
STATISTICS, ALTER TABLE VALIDATE, ALTER TABLE(options etc).

So you would be able to run a VACUUM while an ALTER TABLE VALIDATE was
running, or run an ANALYZE while running CREATE INDEX CONCURRENTLY.

The main blocker to this is that we hold ShareUpdateExclusiveLock on
each command until the end of the transaction.

Obviously there are places we need locks, such as the part of VACUUM
that reads the indexes does need a lock for the duration of the index
scan. The proposal here is to minimize the duration of those locks,
e.g. make VACUUM lock each index in turn and then drop the lock before
moving to the next index, so a DROP INDEX CONCURRENTLY would only be
blocked by a VACUUM if it was scanning that particular index at the
time of the command, and only for the duration of that scan. No doubt
other cases exist.

Removing such locks from the VACUUM/ANALYZE path would prevent autovac
cancelling itself when other forms of DDL are executed.

Proposal would be to add a new lock mode "ShareUpdate", which does not
conflict with itself and yet conflicts with "ShareUpdateExclusive" or
higher. (Hence, it is a strong lock type). DDL would take a
ShareUpdateLock on the table, then during critical portions of
commands it would take a ShareUpdateExclusiveLock and then release it
again before commit.

We would still want to prevent two VACUUMs or two ANALYZEs from
running concurrently, so we would still need a lock mechanism to
prevent that. I'll leave that implementation point open for now since
it could lead to sidetracking away from the main idea.

Implementation would be to introduce the new infrastructure, then make
it work for the VACUUM/CREATE INDEX CONCURRENTLY case, then work
through other commands one by one.

Thoughts?

-- 
Simon Riggs                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Re: Allowing multiple DDL commands to run simultaneously

От
Robert Haas
Дата:
On Mon, Jul 9, 2018 at 6:00 AM, Simon Riggs <simon@2ndquadrant.com> wrote:
> Proposal would be to add a new lock mode "ShareUpdate", which does not
> conflict with itself and yet conflicts with "ShareUpdateExclusive" or
> higher. (Hence, it is a strong lock type). DDL would take a
> ShareUpdateLock on the table, then during critical portions of
> commands it would take a ShareUpdateExclusiveLock and then release it
> again before commit.

I think this would be quite prone to deadlocks.  Suppose someone tries
to grab an AccessExclusiveLock on the table during a window in which
we hold only ShareUpdateLock.  The next attempt to upgrade to
ShareUpdateExclusiveLock will cause a simple deadlock.  In general,
any approach that involves upgrading our lock strength is likely to
have this problem.

You might be able to work around this by inventing a whole new lock
type, say "Relation Maintenance".  Make a rule that you can only take
the "Relation Maintenance" lock while holding a Relation lock with
strength >= ShareUpdateLock and that you do not need to bother
acquiring it if you hold a self-exclusive lock that conflicts with
ShareUpdateLock.  I think that works out to about the same thing as
what you're proposing, except without the deadlock hazard.

In general, though, +1 for trying to do something about this.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Re: Allowing multiple DDL commands to run simultaneously

От
Simon Riggs
Дата:
On 17 July 2018 at 19:47, Robert Haas <robertmhaas@gmail.com> wrote:
> On Mon, Jul 9, 2018 at 6:00 AM, Simon Riggs <simon@2ndquadrant.com> wrote:
>> Proposal would be to add a new lock mode "ShareUpdate", which does not
>> conflict with itself and yet conflicts with "ShareUpdateExclusive" or
>> higher. (Hence, it is a strong lock type). DDL would take a
>> ShareUpdateLock on the table, then during critical portions of
>> commands it would take a ShareUpdateExclusiveLock and then release it
>> again before commit.
>
> I think this would be quite prone to deadlocks.  Suppose someone tries
> to grab an AccessExclusiveLock on the table during a window in which
> we hold only ShareUpdateLock.  The next attempt to upgrade to
> ShareUpdateExclusiveLock will cause a simple deadlock.  In general,
> any approach that involves upgrading our lock strength is likely to
> have this problem.
>
> You might be able to work around this by inventing a whole new lock
> type, say "Relation Maintenance".  Make a rule that you can only take
> the "Relation Maintenance" lock while holding a Relation lock with
> strength >= ShareUpdateLock and that you do not need to bother
> acquiring it if you hold a self-exclusive lock that conflicts with
> ShareUpdateLock.  I think that works out to about the same thing as
> what you're proposing, except without the deadlock hazard.

Yes, it seems better to invent a new orthogonal lock type than have a
new lock level. Thanks.

Seems more like a critical section than a lock.

I'd make code take that lock, even if they have a self-exclusive lock,
just to avoid later problems when the lock level changes.

-- 
Simon Riggs                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services