Обсуждение: BUG #9371: pg_dump acquiring ROW EXCLUSIVE locks on tables

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

BUG #9371: pg_dump acquiring ROW EXCLUSIVE locks on tables

От
dean.a.rasheed@gmail.com
Дата:
The following bug has been logged on the website:

Bug reference:      9371
Logged by:          Dean Rasheed
Email address:      dean.a.rasheed@gmail.com
PostgreSQL version: 8.4.20
Operating system:   Linux
Description:

[Spotted in 8.4, but also tested in 9.4devel]

On one of our production systems we are having a problem that some client
processes are being blocked by pg_dump, and therefore having to wait a long
time before they can run. The clients in question are attempting to obtain
an explicit SHARE lock on a table to prevent concurrent data changes, and it
turns out that pg_dump is obtaining a ROW EXCLUSIVE lock on those tables for
the duration of the dump.

Further digging revealed that pg_dump obtains a ROW EXCLUSIVE lock on any
table mentioned in an INSERT, UPDATE or DELETE RULE. Wondering how that can
happen, I tried the following test case, describing a relation:

CREATE TABLE t (a int);
CREATE VIEW v AS SELECT * FROM t;
CREATE RULE r AS ON INSERT TO v DO INSTEAD INSERT INTO t VALUES(NEW.a);

BEGIN;
\d+ v
SELECT mode FROM pg_locks where relation = 't'::regclass;
COMMIT;

Result:

       mode
------------------
 AccessShareLock
 RowExclusiveLock
(2 rows)

whereas I would expect at most an ACCESS SHARE lock.

The reason is that in ruleutils.c, pg_get_ruledef()/make_ruledef() and
get_query_def() are calling AcquireRewriteLocks() on the rule query, which
acquires a ROW EXCLUSIVE lock on its target table, even though the query is
not about to be run in this context. The calls to AcquireRewriteLocks() do
seem to be necessary to handle dropped columns, but perhaps
AcquireRewriteLocks() could be told that the query is not about to be run in
this case, and that it should only acquire ACCESS SHARE locks on the
tables.

Regards,
Dean

Re: BUG #9371: pg_dump acquiring ROW EXCLUSIVE locks on tables

От
Dean Rasheed
Дата:
On 27 February 2014 11:54,  <dean.a.rasheed@gmail.com> wrote:
> [snip]
> perhaps
> AcquireRewriteLocks() could be told that the query is not about to be run in
> this case, and that it should only acquire ACCESS SHARE locks on the
> tables.
>

Here's a patch for HEAD along those lines.

I've tested it on our production data and confirmed that with this
patch pg_dump no longer acquires exclusive locks. I think this should
be back-patched, since we do promise that pg_dump does not block other
readers or writers.

Regards,
Dean

Вложения

Re: BUG #9371: pg_dump acquiring ROW EXCLUSIVE locks on tables

От
Tom Lane
Дата:
Dean Rasheed <dean.a.rasheed@gmail.com> writes:
> Here's a patch for HEAD along those lines.

> I've tested it on our production data and confirmed that with this
> patch pg_dump no longer acquires exclusive locks. I think this should
> be back-patched, since we do promise that pg_dump does not block other
> readers or writers.

I think this patch looks generally sane, and I agree that the excess
locking is a bug worthy of being back-patched.  But is anyone concerned
about changing the signature of AcquireRewriteLocks() in back branches?
I can't immediately think of a reason why extensions might be calling it,
but ...

We could avoid a signature change in back branches by making
AcquireRewriteLocks() into a wrapper around some new function.
But I don't want to do it like that in HEAD, so this would create
a divergence between HEAD and back branches.

I'm inclined to think a signature change is OK.  Objections?

            regards, tom lane