Re: Alter index rename concurrently to - Mailing list pgsql-hackers

From Andres Freund
Subject Re: Alter index rename concurrently to
Date
Msg-id 20181013020131.waeojm6anbs4mavy@alap3.anarazel.de
Whole thread Raw
In response to Re: Alter index rename concurrently to  (Peter Eisentraut <peter.eisentraut@2ndquadrant.com>)
Responses Re: Alter index rename concurrently to
List pgsql-hackers
Hi,

On 2018-10-05 12:03:54 +0200, Peter Eisentraut wrote:
> From 37591a06901e2d694e3928b7e1cddfcfd84f6267 Mon Sep 17 00:00:00 2001
> From: Peter Eisentraut <peter_e@gmx.net>
> Date: Mon, 13 Aug 2018 22:38:36 +0200
> Subject: [PATCH v2] Lower lock level for renaming indexes
> 
> Change lock level for renaming index (either ALTER INDEX or implicitly
> via some other commands) from AccessExclusiveLock to
> ShareUpdateExclusiveLock.
> 
> The reason we need a strong lock at all for relation renaming is that
> the name change causes a rebuild of the relcache entry.  Concurrent
> sessions that have the relation open might not be able to handle the
> relcache entry changing underneath them.  Therefore, we need to lock the
> relation in a way that no one can have the relation open concurrently.
> But for indexes, the relcache handles reloads specially in
> RelationReloadIndexInfo() in a way that keeps changes in the relcache
> entry to a minimum.  As long as no one keeps pointers to rd_amcache and
> rd_options around across possible relcache flushes, which is the case,
> this ought to be safe.
> 
> One could perhaps argue that this could all be done with an
> AccessShareLock then.  But we standardize here for consistency on
> ShareUpdateExclusiveLock, which is already used by other DDL commands
> that want to operate in a concurrent manner.  For example, renaming an
> index concurrently with CREATE INDEX CONCURRENTLY might be trouble.

I don't see how this could be argued. It has to be a self-conflicting
lockmode, otherwise you'd end up doing renames of tables where you
cannot see the previous state. And you'd get weird errors about updating
invisible rows etc.


> @@ -3155,11 +3157,13 @@ RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal)
>      Oid            namespaceId;
>  
>      /*
> -     * Grab an exclusive lock on the target table, index, sequence, view,
> -     * materialized view, or foreign table, which we will NOT release until
> -     * end of transaction.
> +     * Grab a lock on the target relation, which we will NOT release until end
> +     * of transaction.  The lock here guards mainly against triggering
> +     * relcache reloads in concurrent sessions, which might not handle this
> +     * information changing under them.  For indexes, we can use a reduced
> +     * lock level because RelationReloadIndexInfo() handles indexes specially.
>       */

I don't buy this description. Imo it's a fundamental correctness
thing. Without it concurrent DDL would potentially overwrite the rename,
because they could start updating while still seeing the old version.


Greetings,

Andres Freund


pgsql-hackers by date:

Previous
From: Andres Freund
Date:
Subject: Re: [HACKERS] removing abstime, reltime, tinterval.c, spi/timetravel
Next
From: "Bossart, Nathan"
Date:
Subject: Re: Maximum password length