Обсуждение: More information on how to understand table pg_locks.

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

More information on how to understand table pg_locks.

От
"Olivier Ceulemans"
Дата:

Hi All,

 

I wrote an application making ‘advanced’ use of transactions. The application is not tied to a specific kind of database. It runs fine on oracle, db2, sql server but I run into a deadlock on postgresql.

I have two transactions (let’s say A & B). These two transactions are initiated by the same thread and I’m alone on the database and the problem can be reproduced at will on postgresql. So this is not a random problem.

 

I try to understand what I see in the pg_locks table but it looks like what is found there should never occur according to the manual…

 

 

At deadlock time:

For transaction A, I have a RowShareLock on table X. I have no idea on how/why this RowShareLock is acquired by my application. In transaction A, I never read/write ‘directly’ to the table X. However I create data in other tables that have foreign keys to table X.

-> Is there more information available somewhere in postgres system tables ?

-> Could these foreign keys be the cause of this RowShareLock ?

 

For transaction B, I have a AccessShareLock, ExclusiveLock and RowExclusiveLock on table X.

-> According to the manual, ExclusiveLock occurs only on system tables.

-> Is there a way to find why this lock is acquired ?

 

Do you know tools to help in debugging this ?

 

Any help is appreciated…

 

Thanks in advance

 

Re: More information on how to understand table pg_locks.

От
Tom Lane
Дата:
"Olivier Ceulemans" <Olivier.Ceulemans@irislink.com> writes:
> I wrote an application making 'advanced' use of transactions. The
> application is not tied to a specific kind of database. It runs fine on
> oracle, db2, sql server but I run into a deadlock on postgresql.
> ...
> For transaction A, I have a RowShareLock on table X. I have no idea on
> how/why this RowShareLock is acquired by my application. In transaction
> A, I never read/write 'directly' to the table X. However I create data
> in other tables that have foreign keys to table X.

What Postgres version is this?  Before 8.1 we used exclusive row locks
to enforce that referenced rows didn't go away before a referencing
row could be committed, and this made it easy to hit unexpected
deadlocks.

            regards, tom lane

Re: More information on how to understand table pg_locks.

От
"Olivier Ceulemans"
Дата:
I'm running 'PostgreSQL 8.2.0 on i686pc-mingw32, compiled by GCC gcc.exe
(GCC) 3.4.2 (mingw-special)'.

My intuition about the lock acquired foreign keys seems right.

Here is a short description: (if it can help someone else one day...)
create table y
{
    y_id bigint not null,
    y_count int not null,
    primary key (y_id)
}

create table x
{
    x_id bigint not null,
    x_y_id bigint not null,
    primary key (x_id),
    foreign key (x_id) references y(y_id)
};

Transaction A:
    0: begin
    1: insert into x (x_id, x_y_id) values (0, 0)

Transaction B:
    2: begin
    3: select * from y
    4: update y set y_count=y_count+1 where y_id=0
    5: commit

Transaction A:
    6: commit

Transaction B is simply blocked by transaction A at step 4.
Since these two transactions are in the same thread, my application
freezes.
If I declare the foreign key as 'deferable initially defered' there is
no freeze because the lock on y is acquired just before the commit in
transaction A. So I found a solution to my problem.

Now I understand what happen.
Now I'm worried it doesn't happen on other rdbms. :-)

I will write a small/simplified test case for my application and try to
run it on every supported rdbms and validate what I say more precisely.
Other rdbms seems not to block in this scenario. But, once understood,
the behaviour of postgresql seems perfectly reasonable.

Thanks for your help !



-----Original Message-----
From: Tom Lane [mailto:tgl@sss.pgh.pa.us]
Sent: mardi 13 mars 2007 16:57
To: Olivier Ceulemans
Cc: pgsql-general@postgresql.org
Subject: Re: [GENERAL] More information on how to understand table
pg_locks.

"Olivier Ceulemans" <Olivier.Ceulemans@irislink.com> writes:
> I wrote an application making 'advanced' use of transactions. The
> application is not tied to a specific kind of database. It runs fine
on
> oracle, db2, sql server but I run into a deadlock on postgresql.
> ...
> For transaction A, I have a RowShareLock on table X. I have no idea on
> how/why this RowShareLock is acquired by my application. In
transaction
> A, I never read/write 'directly' to the table X. However I create data
> in other tables that have foreign keys to table X.

What Postgres version is this?  Before 8.1 we used exclusive row locks
to enforce that referenced rows didn't go away before a referencing
row could be committed, and this made it easy to hit unexpected
deadlocks.

            regards, tom lane

Re: More information on how to understand table pg_locks.

От
Tom Lane
Дата:
"Olivier Ceulemans" <Olivier.Ceulemans@irislink.com> writes:
> I'm running 'PostgreSQL 8.2.0 on i686pc-mingw32, compiled by GCC gcc.exe
> (GCC) 3.4.2 (mingw-special)'.

BTW: you oughta think about an update to 8.2.3; we've fixed several nasty
bugs, most especially in the windows port.

> Transaction B is simply blocked by transaction A at step 4.

Right, because A has a share lock on the row that B wants to update.
This is to ensure that nobody deletes that row or changes its key value
before A's new row is committed and visible.  (Until that happens, a
would-be deleter would see no reason he couldn't do it.)

> Now I understand what happen.
> Now I'm worried it doesn't happen on other rdbms. :-)

There's been some discussion of trying to lock only the key columns,
ie, allow updates that just change non-key columns.  It's not at all
clear how to do that within Postgres though.  The other systems you
tried probably have different approaches to this problem.

            regards, tom lane