Обсуждение: Is this the expected behaviour for DDL-query execution?

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

Is this the expected behaviour for DDL-query execution?

От
Thomas Johansson
Дата:
Hi,

I am using PG 8.2.11 with psycopg2 2.0.6 (Python) in a multithreaded
application. Each thread keeps its own DB-connection.

The tables in the applications DB are partitioned with help of triggers
for redirection of INSERTS (only triggers for INSERTS, not for DELETE or
UPDATES, we rely on constraint exclusion for that part).

When performing an DROP TABLE query on a partition when one or more
other threads are at the same time performing updates on the very same
partitioned table (UPDATES which does not reference the partition key
column!, i.e. all available partitions has to be checked for the row to
be updated) which the partition are being dropped from I get the
following errors:

pg_log:
2009-05-10 00:00:41.451 CEST> ERROR:  could not open relation with OID 24223
2009-05-10 00:00:41.451 CEST> STATEMENT:
                UPDATE state_change SET (final_view_time, end_time) =
(33, 8745) WHERE id = 76306866

My applications log:
2009-05-10 00:00:41,394 SystemLog            INFO: Dropped partition
table state_change_20090425

After the table has been dropped these errors disappears and everything
is nice and neat until 24 hours later when is time to drop the next
partition etc.

As I understand, it should be perfectly okay to perform DDL-queries at
the same time as performing DML-queries? Or do I have to make sure to
provide exclusive access to the DB while performing DDL-queries? Is
there anything in the PG documentation regarding this, I have looked but
has found nothing of interest so far.

I am planning to add a WHERE clause to the UPDATE statement ithh the
paritioning column, which I guess might solve the immediate problem, but
it would still be nice to be able to perform more general updates
without specifying constraints on the partitioning column.

Best Regards,
Thomas

Re: Is this the expected behaviour for DDL-query execution?

От
Tom Lane
Дата:
Thomas Johansson <thomas.johansson@agama.tv> writes:
> When performing an DROP TABLE query on a partition when one or more
> other threads are at the same time performing updates on the very same
> partitioned table (UPDATES which does not reference the partition key
> column!, i.e. all available partitions has to be checked for the row to
> be updated) which the partition are being dropped from I get the
> following errors:

> pg_log:
> 2009-05-10 00:00:41.451 CEST> ERROR:  could not open relation with OID 24223

Yeah, this is possible because DROP TABLE does not attempt to acquire
exclusive lock on the victim table's parent(s).  So if a concurrent
query operating on the parent had already obtained the victim table's
OID from pg_inherit, it would get this failure.

It's somewhat annoying but I'm not sure the cure wouldn't be worse than
the disease.  In particular, a straight attempt to lock the parent would
result in deadlock failures in exactly the cases where you get this
error now.

            regards, tom lane

Re: Is this the expected behaviour for DDL-query execution?

От
Thomas Johansson
Дата:
> Yeah, this is possible because DROP TABLE does not attempt to acquire
> exclusive lock on the victim table's parent(s).  So if a concurrent
> query operating on the parent had already obtained the victim table's
> OID from pg_inherit, it would get this failure.
>
> It's somewhat annoying but I'm not sure the cure wouldn't be worse than
> the disease.  In particular, a straight attempt to lock the parent would
> result in deadlock failures in exactly the cases where you get this
> error now.
>
>             regards, tom lane
>

Thank you very much for the informative answer :-)

 So what would be the best/easiest way to circumvent this behaviour
while still allowing concurrent queries? I tried to implement a solution
which I hoped would fix this by first doing NO INHERIT on the partition
which were to be dropped and then later (an hour later, to be absolutely
sure that no query were still using the table) dropping the table.
However this resulted in the following type of problem instead, which I
guess is just another symptom of the locking strategy described by you
above?

ProgrammingError: could not find inherited attribute "id" of relation
"state_change_20090429"

I initially stumbled upon this problem when changing from using rules to
triggers for table partitioning (for improved scalability). When we were
using rules this kind of problem did not exist which I suspect is a side
affect caused by the base table "owning" the partitioning rules?

So I believe my best remaining option is to add UPDATE triggers to the
base tables, that would help right? Or can the "rules side affect" be
simulated some way?

I guess that I am not the only one who has stumbled upon this problem?
Probably the PG manual should mention something about this together with
a proposed workaround?

Best Regards,
Thomas

Re: Is this the expected behaviour for DDL-query execution?

От
Tom Lane
Дата:
Thomas Johansson <thomas.johansson@agama.tv> writes:
>  So what would be the best/easiest way to circumvent this behaviour
> while still allowing concurrent queries? I tried to implement a solution
> which I hoped would fix this by first doing NO INHERIT on the partition
> which were to be dropped and then later (an hour later, to be absolutely
> sure that no query were still using the table) dropping the table.
> However this resulted in the following type of problem instead, which I
> guess is just another symptom of the locking strategy described by you
> above?

> ProgrammingError: could not find inherited attribute "id" of relation
> "state_change_20090429"

What PG version are you using?  In 8.3 it seems to work automatically,
although in prior versions you could well have some problems with cached
plans not getting invalidated.  If it is 8.3 I'd like to see a detailed
example.

FWIW, we have implemented a trial solution to your original complaint
for 8.4:
http://archives.postgresql.org/pgsql-committers/2009-05/msg00208.php

            regards, tom lane

Re: Is this the expected behaviour for DDL-query execution?

От
Thomas Johansson
Дата:
Tom Lane wrote:
> What PG version are you using?
8.2.11
>   In 8.3 it seems to work automatically,
> although in prior versions you could well have some problems with cached
> plans not getting invalidated.
Any proposed workaround?

Would SELECTs be affected by this too?

(detaild log message from pg_log
2009-05-15 00:00:17.179 CEST> LOCATION:  make_inh_translation_lists,
prepunion.c:992
2009-05-15 00:00:17.179 CEST> STATEMENT:
                UPDATE state_change SET (final_view_time, end_time) =
(226, 10528) WHERE id = 91332641 AND time = 10523

2009-05-15 00:00:17.179 CEST> ERROR:  XX000: could not find inherited
attribute "id" of relation "state_change_20090430")

> FWIW, we have implemented a trial solution to your original complaint
> for 8.4:
> http://archives.postgresql.org/pgsql-committers/2009-05/msg00208.php
>
Nice :-) Although for now I will need to get this working on 8.2.x.

Does this leave me with UPDATE triggers as the best viable (is it
viable?) solution?

Are there, as mentioned in previous post, some way to simulate the way
the DB behaved when using rules for partitioning?

Best Regards
Thomas

Re: Is this the expected behaviour for DDL-query execution?

От
Tom Lane
Дата:
Thomas Johansson <thomas.johansson@agama.tv> writes:
> (detaild log message from pg_log
> 2009-05-15 00:00:17.179 CEST> LOCATION:  make_inh_translation_lists,
> prepunion.c:992
> 2009-05-15 00:00:17.179 CEST> STATEMENT:
>                 UPDATE state_change SET (final_view_time, end_time) =
> (226, 10528) WHERE id = 91332641 AND time = 10523

> 2009-05-15 00:00:17.179 CEST> ERROR:  XX000: could not find inherited
> attribute "id" of relation "state_change_20090430")

I'm still curious to see a complete test case for this behavior.  AFAICS
the only way you could get that failure after an ALTER NO INHERIT would
be if the planner saw the changes to the child relation but did not see
the removal of the pg_inherits entry; which seems improbable.

            regards, tom lane