Обсуждение: Deadlock Problem

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

Deadlock Problem

От
Gavin Love
Дата:
I am getting a number of deadlock errors in my log files and I was
wondering if anyone knows how I can stop them.

Query failed: ERROR:  deadlock detected DETAIL:  Process 11931 waits for
ShareLock on transaction 148236867; blocked by process 11932. Process
11932 waits for ShareLock on transaction 148236866; blocked by process
11931.

This is for a web application. Whenever a search result is displayed I
need to update a counter to say it has been viewed which is done with
between 1 and 15 updates in one transaction of the form.

BEGIN;
UPDATE stats SET click_count = click_count+1 WHERE id = '122'
UPDATE stats SET click_count = click_count+1 WHERE id = '123'
UPDATE stats SET click_count = click_count+1 WHERE id = '124'
etc...
COMMIT;

My lock management config is:
deadlock_timeout = 2000 # in milliseconds
#max_locks_per_transaction = 64 # min 10, ~200*max_connections bytes

I am using Postgres 8.0.3

Does anyone know how I can stop these deadlocks from occurring?

They are not a big problem as losing a few it only happens a couple of
times a day but I prefer to have everything working as it should.

Thanks

Gavin


Re: Deadlock Problem

От
Csaba Nagy
Дата:
Gavin,

Are you ordering the updates by id inside one transaction ? You should
order the execution of the statements by id inside a transaction, and
the deadlocks should go away.

HTH,
Csaba.

On Wed, 2005-06-15 at 13:10, Gavin Love wrote:
> I am getting a number of deadlock errors in my log files and I was
> wondering if anyone knows how I can stop them.
>
> Query failed: ERROR:  deadlock detected DETAIL:  Process 11931 waits for
> ShareLock on transaction 148236867; blocked by process 11932. Process
> 11932 waits for ShareLock on transaction 148236866; blocked by process
> 11931.
>
> This is for a web application. Whenever a search result is displayed I
> need to update a counter to say it has been viewed which is done with
> between 1 and 15 updates in one transaction of the form.
>
> BEGIN;
> UPDATE stats SET click_count = click_count+1 WHERE id = '122'
> UPDATE stats SET click_count = click_count+1 WHERE id = '123'
> UPDATE stats SET click_count = click_count+1 WHERE id = '124'
> etc...
> COMMIT;
>
> My lock management config is:
> deadlock_timeout = 2000 # in milliseconds
> #max_locks_per_transaction = 64 # min 10, ~200*max_connections bytes
>
> I am using Postgres 8.0.3
>
> Does anyone know how I can stop these deadlocks from occurring?
>
> They are not a big problem as losing a few it only happens a couple of
> times a day but I prefer to have everything working as it should.
>
> Thanks
>
> Gavin
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
>       subscribe-nomail command to majordomo@postgresql.org so that your
>       message can get through to the mailing list cleanly


Re: Deadlock Problem

От
Gavin Love
Дата:
Hi Csaba,

I am not ordering them by ID as in reality the where condition is more
complex than in my example

UPDATE stats SET click_count = click_count+1 WHERE month = '06' AND year
= '2005' AND type = 'a' AND id = '123' AND count_type = 'b'";

Can you explain why sorting by ID would make a difference as I don't
understand why what you are suggesting should make a difference?

Thanks,

Gavin

Csaba Nagy wrote:
> Gavin,
>
> Are you ordering the updates by id inside one transaction ? You should
> order the execution of the statements by id inside a transaction, and
> the deadlocks should go away.
>
> HTH,
> Csaba.
>
> On Wed, 2005-06-15 at 13:10, Gavin Love wrote:
>
>>I am getting a number of deadlock errors in my log files and I was
>>wondering if anyone knows how I can stop them.
>>
>>Query failed: ERROR:  deadlock detected DETAIL:  Process 11931 waits for
>>ShareLock on transaction 148236867; blocked by process 11932. Process
>>11932 waits for ShareLock on transaction 148236866; blocked by process
>>11931.
>>
>>This is for a web application. Whenever a search result is displayed I
>>need to update a counter to say it has been viewed which is done with
>>between 1 and 15 updates in one transaction of the form.
>>
>>BEGIN;
>>UPDATE stats SET click_count = click_count+1 WHERE id = '122'
>>UPDATE stats SET click_count = click_count+1 WHERE id = '123'
>>UPDATE stats SET click_count = click_count+1 WHERE id = '124'
>>etc...
>>COMMIT;
>>
>>My lock management config is:
>>deadlock_timeout = 2000 # in milliseconds
>>#max_locks_per_transaction = 64 # min 10, ~200*max_connections bytes
>>
>>I am using Postgres 8.0.3
>>
>>Does anyone know how I can stop these deadlocks from occurring?
>>
>>They are not a big problem as losing a few it only happens a couple of
>>times a day but I prefer to have everything working as it should.
>>
>>Thanks
>>
>>Gavin
>>
>>
>>---------------------------(end of broadcast)---------------------------
>>TIP 3: if posting/reading through Usenet, please send an appropriate
>>      subscribe-nomail command to majordomo@postgresql.org so that your
>>      message can get through to the mailing list cleanly
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster
>

Re: Deadlock Problem

От
Csaba Nagy
Дата:
Because I guess id is your primary key, and that would make your
transactions always update the same rows in the same order. It really
doesn't matter if you have other criteria in the where clause, the
issuing order of the statements is the problem.
Deadlock will occur if 2 concurrent transactions are updating the same
rows in different order, so ordering will eliminate the deadlocks.

A typical deadlock scenario:

T1=transaction 1;
T2=transaction 2;

T1 starts;
T2 starts;
T1 updates id 1;
T2 updates id 2;
T1 wants to update id 2, but the row is locked by T2;
T2 wants to update id 1, but the row is locked by T1;
deadlock: both transactions wait for the other one to finish.

Now if both will try to update id 1 first and then id 2, it would be:

T1 starts;
T2 starts;
T1 updates id 1;
T2 wants to update id 1, but the row is locked by T1;
T1 updates id 2;
...
T1 finishes;
T2 updates id 1;
T2 updates id 2;
...
T2 finishes;


Generally, ordering in the same way the rows being updated in all
transactions in a system will eliminate most of the deadlocks.

HTH,
Csaba.


On Wed, 2005-06-15 at 13:58, Gavin Love wrote:
> Hi Csaba,
>
> I am not ordering them by ID as in reality the where condition is more
> complex than in my example
>
> UPDATE stats SET click_count = click_count+1 WHERE month = '06' AND year
> = '2005' AND type = 'a' AND id = '123' AND count_type = 'b'";
>
> Can you explain why sorting by ID would make a difference as I don't
> understand why what you are suggesting should make a difference?
>
> Thanks,
>
> Gavin
>
> Csaba Nagy wrote:
> > Gavin,
> >
> > Are you ordering the updates by id inside one transaction ? You should
> > order the execution of the statements by id inside a transaction, and
> > the deadlocks should go away.
> >
> > HTH,
> > Csaba.
> >
> > On Wed, 2005-06-15 at 13:10, Gavin Love wrote:
> >
> >>I am getting a number of deadlock errors in my log files and I was
> >>wondering if anyone knows how I can stop them.
> >>
> >>Query failed: ERROR:  deadlock detected DETAIL:  Process 11931 waits for
> >>ShareLock on transaction 148236867; blocked by process 11932. Process
> >>11932 waits for ShareLock on transaction 148236866; blocked by process
> >>11931.
> >>
> >>This is for a web application. Whenever a search result is displayed I
> >>need to update a counter to say it has been viewed which is done with
> >>between 1 and 15 updates in one transaction of the form.
> >>
> >>BEGIN;
> >>UPDATE stats SET click_count = click_count+1 WHERE id = '122'
> >>UPDATE stats SET click_count = click_count+1 WHERE id = '123'
> >>UPDATE stats SET click_count = click_count+1 WHERE id = '124'
> >>etc...
> >>COMMIT;
> >>
> >>My lock management config is:
> >>deadlock_timeout = 2000 # in milliseconds
> >>#max_locks_per_transaction = 64 # min 10, ~200*max_connections bytes
> >>
> >>I am using Postgres 8.0.3
> >>
> >>Does anyone know how I can stop these deadlocks from occurring?
> >>
> >>They are not a big problem as losing a few it only happens a couple of
> >>times a day but I prefer to have everything working as it should.
> >>
> >>Thanks
> >>
> >>Gavin
> >>
> >>
> >>---------------------------(end of broadcast)---------------------------
> >>TIP 3: if posting/reading through Usenet, please send an appropriate
> >>      subscribe-nomail command to majordomo@postgresql.org so that your
> >>      message can get through to the mailing list cleanly
> >
> >
> >
> > ---------------------------(end of broadcast)---------------------------
> > TIP 4: Don't 'kill -9' the postmaster
> >


Re: Deadlock Problem

От
Tom Lane
Дата:
Csaba Nagy <nagy@ecircle-ag.com> writes:
>> Can you explain why sorting by ID would make a difference as I don't
>> understand why what you are suggesting should make a difference?
>
> Because I guess id is your primary key, and that would make your
> transactions always update the same rows in the same order.

If the deadlocks occur because different transactions actually try to
update the same rows concurrently, then this is an appropriate solution.

However I wonder if Gavin is getting bitten by foreign key deadlocks.
Is there any foreign key reference from the stats table to other tables?

            regards, tom lane

Re: Deadlock Problem

От
Gavin Love
Дата:
> If the deadlocks occur because different transactions actually try to
> update the same rows concurrently, then this is an appropriate solution.
>
> However I wonder if Gavin is getting bitten by foreign key deadlocks.
> Is there any foreign key reference from the stats table to other tables?

Tom,

There are no foreign key references to or from this table as the updates
to it consume a large % of the overall DB activity so I kept everything
to a minimum.

I think Csaba has spotted the real problem but given that changing the
order is not that easy and these stats are not mission critical I may
just live with the odd deadlock. At least I understand why this is
happening now.

Thanks,

Gavin