Thread: does reindex need exclusive table access?

does reindex need exclusive table access?

From
"Gauthier, Dave"
Date:

v8.3.4 on linux.

 

Does "reindex table foo" require no other users accessing the foo table?  Trying to understand why this seems to be stalled when I attempt this on a live DB (if runs fine/fast on a copy of the DB that no one uses).

 

Should I run this inside a transaction?

 

Thanks in Advance !  

Re: does reindex need exclusive table access?

From
Craig Ringer
Date:
On 01/11/11 02:51, Gauthier, Dave wrote:
> v8.3.4 on linux.
>
>
>
> Does "reindex table foo" require no other users accessing the foo
> table?  Trying to understand why this seems to be stalled when I attempt
> this on a live DB (if runs fine/fast on a copy of the DB that no one uses).

Yes, it requires an exclusive lock.

It doesn't matter whether or not you run it as part of an explicit
transaction.

There is not currently any 'REINDEX CONCURRENTLY' command - not unless
it's been added in a very recent version and I haven't noticed yet. You
can CREATE INDEX CONCURRENTLY then drop the old index, though.

A workaround for reindexing while live is to begin a transaction, create
the new index with a new name, drop the old one, rename the new one to
the old one, and commit. This only requires an exclusive lock for the
period of the drop and rename. On more recent versions you can even use
this for indexes that implement primary key or unique constrants by
using the 'ADD CONSTRAINT ... USING INDEX ...' syntax; see:

  http://www.postgresql.org/docs/current/static/sql-altertable.html

--
Craig Ringer

Re: does reindex need exclusive table access?

From
Tom Lane
Date:
Craig Ringer <ringerc@ringerc.id.au> writes:
> On 01/11/11 02:51, Gauthier, Dave wrote:
>> Does "reindex table foo" require no other users accessing the foo
>> table?  Trying to understand why this seems to be stalled when I attempt
>> this on a live DB (if runs fine/fast on a copy of the DB that no one uses).

> Yes, it requires an exclusive lock.
> There is not currently any 'REINDEX CONCURRENTLY' command - not unless
> it's been added in a very recent version and I haven't noticed yet. You
> can CREATE INDEX CONCURRENTLY then drop the old index, though.

Yeah.  The hard part of that is not actually the "reindex", it's the
"drop the old index" ... because the old index might be in use by
concurrent SELECTs.  So dropping the old index absolutely requires an
exclusive lock, to ensure there are no read-only transactions depending
on that version of the index.  Building a new index can be done with
a much weaker lock.

A straight reindex doesn't have a lot of choice here.  We could have it
take a lesser lock while it's rebuilding the index, and then try to
upgrade to exclusive lock to move the new version into place --- but
upgrading your lock is a well-known recipe for causing deadlocks.

The one good thing about build-a-new-index-with-REINDEX-CONCURRENTLY-
and-then-drop-the-old-index is that the DROP requires exclusive lock
for only a tiny amount of time, and if the DROP does fail and roll back
because of conflicts, you haven't lost the work of building the new
index version.  You can just try the DROP again.

> A workaround for reindexing while live is to begin a transaction, create
> the new index with a new name, drop the old one, rename the new one to
> the old one, and commit. This only requires an exclusive lock for the
> period of the drop and rename.

I'd do that in two transactions, so you don't lose the rebuild work
if there's a problem getting exclusive lock.

            regards, tom lane

Re: does reindex need exclusive table access?

From
Vincent de Phily
Date:
On Tuesday 01 November 2011 12:00:33 Craig Ringer wrote:
> A workaround for reindexing while live is to begin a transaction, create
> the new index with a new name, drop the old one, rename the new one to
> the old one, and commit. This only requires an exclusive lock for the
> period of the drop and rename. On more recent versions you can even use
> this for indexes that implement primary key or unique constrants by
> using the 'ADD CONSTRAINT ... USING INDEX ...' syntax; see:
>
>   http://www.postgresql.org/docs/current/static/sql-altertable.html

Been happily doing this (without worrying about transactions, as Tom
suggested), but couldn't quite figure out how to do it with my primary key
indexes on 8.3. Do I have to bite the bullet and take an exclusive lock (or
upgrade to 9.1) ?

The technique kinda works (with some changes) using unique indexes however. Is
there a functional difference between a unique index and a primary key index
(knowing that my column is not null) ? Or is it just for documentation and ORM
purposes ?


--
Vincent de Phily

Re: does reindex need exclusive table access?

From
Tom Lane
Date:
Vincent de Phily <vincent.dephily@mobile-devices.fr> writes:
> The technique kinda works (with some changes) using unique indexes however. Is
> there a functional difference between a unique index and a primary key index
> (knowing that my column is not null) ? Or is it just for documentation and ORM
> purposes ?

The only functional difference is that a foreign key declaration
referring to the table ("REFERENCES tabname") will default to the pkey
column list.  If you haven't got a declared pkey then you have to spell
out the column list.

            regards, tom lane