Thread: [BUG] Deadlock detected when update with multiple clients

[BUG] Deadlock detected when update with multiple clients

From
"tanghy.fnst@fujitsu.com"
Date:
Hi

I met a deadlock when I update amounts of text-type data with multiple clients.
And there's no deadlock if I set autovacuum to off. Error messages about the
deadlock are as follows.

2021-09-14 09:18:40.392 CST [428452] ERROR:  deadlock detected
2021-09-14 09:18:40.392 CST [428452] DETAIL:  Process 428452 waits for ShareLock on transaction 1725; blocked by
process428455. 
        Process 428455 waits for ShareLock on transaction 1723; blocked by process 428452.
        Process 428452: UPDATE tbl SET body = upper(body);
        Process 428455: UPDATE tbl SET body = upper(body);
2021-09-14 09:18:40.392 CST [428452] HINT:  See server log for query details.
2021-09-14 09:18:40.392 CST [428452] CONTEXT:  while rechecking updated tuple (0,1) in relation "tbl"
2021-09-14 09:18:40.392 CST [428452] STATEMENT:  UPDATE tbl SET body = upper(body);

I'm not sure if I used it inappropriately, or it's unexpected. Could someone
take a look at this problem?

Attach a script to reproduce it. It took about 2~3 minutes to run it on my
machine.

FYI, I found this problem on HEAD and I could reproduce at PG14 and PG13. I
didn't try other versions.

Regards
Tang

Attachment

Re: [BUG] Deadlock detected when update with multiple clients

From
hubert depesz lubaczewski
Date:
On Tue, Sep 14, 2021 at 03:03:40AM +0000, tanghy.fnst@fujitsu.com wrote:
> I met a deadlock when I update amounts of text-type data with multiple clients.
> And there's no deadlock if I set autovacuum to off. Error messages about the
> deadlock are as follows.

Autovacuum is red herring.
Your queries deadlock because they update all the rows in random order,
so sometimes it goes into deadlock condition.

This is known, is not a bug.

When you're doing multiple updates that might update the same rows (and
yours definitely do), it is important to update them in the same order.

Or lock before.

It's hard to provide solid advise in here, since your test case is
clearly bogus - there is no reason to run more than 1 update of whole
table, with the same update clause, at once.

depesz