Re: Deadlock bug - Mailing list pgsql-hackers

From Joel Jacobson
Subject Re: Deadlock bug
Date
Msg-id AANLkTi=uNywV-xqas79NQJ=ZsFJQXf3HEL90=M_LF=H2@mail.gmail.com
Whole thread Raw
In response to Re: Deadlock bug  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Deadlock bug
List pgsql-hackers
Hm, in my example, there are no INSERTs in the two conflicting transactions?
The suggestion on adding an ON INSERT trigger would have no effect as far as I can see.
The comment from trigger.c is also about INSERT, can't see how it affects us.

I don't understand exactly why this deadlock occurs, but the one thing I cannot understand is why process 2 is not allowed to update the same row, which it has already updated in the same transaction.

In general, if a transaction has a "write row lock" (or what ever it is called in postgres), i.e., exclusive right to modify the row in the table, shouldn't that same transaction always be allowed to update the same row in a later stage? I understand the foreign key is the reason for the conflict, but process 2 doesn't attempt to modify the foreign key data, it only does update on table B.

It just doesn't make sense to abort process 2 with a deadlock in my example.

(If it helps, we would be willing to assign a bounty prize to anyone taking on the task to solve this problem.)

Best regards,

Joel Jacobson
Glue Finance


2010/8/20 Tom Lane <tgl@sss.pgh.pa.us>
"Kevin Grittner" <Kevin.Grittner@wicourts.gov> writes:
> The surprising thing is that a particular row is (using the
> identifiers from the attachment):

> Process 2 updates a particular row without blocking.
> Process 1 updates the same row, which blocks.
> Process 2 updates the same row again (with *exactly* the same UPDATE
> statement), which fails with a deadlock.

> I'm not sure I consider that a bug, but it moves the needle on the
> astonishment meter.

OK, I looked a bit closer.  The first update in process 2 is changing
a row in B that has an FK reference to an already-modified row in A.
The only reason that doesn't block is that we optimize away taking a
sharelock on the referenced row if the update doesn't change the FK
column(s), as this doesn't.  However, the *second* update doesn't
get the benefit of that optimization, as per this comment in trigger.c:

                    * There is one exception when updating FK tables: if the
                    * updated row was inserted by our own transaction and the
                    * FK is deferred, we still need to fire the trigger. This
                    * is because our UPDATE will invalidate the INSERT so the
                    * end-of-transaction INSERT RI trigger will not do
                    * anything, so we have to do the check for the UPDATE
                    * anyway.

So it goes and waits for sharelock on the A row, and then you have a
deadlock because process 1 has exclusive lock on that row and is already
blocked waiting for process 2.

The Glue guys aren't the first to complain of this behavior, so it'd
be nice to improve it.

If we knew that the already-updated row was one for which we'd been able
to optimize away the FK check, then we could do so again on the second
update (assuming it still didn't change the FK columns), but I don't see
any practical way to know that.  We only have our hands on the current
update's old and new tuples, not on previous versions; and there's no
convenient way to find the previous version because the update ctid
links run the other way.

[ thinks for awhile... ]  Conceivably we could get around this by
programming the ON INSERT trigger to chase forward to the latest live
row version, rather than just doing nothing when the initially inserted
row has been outdated.  It'd be a pretty ticklish thing to get right,
though.

                       regards, tom lane



--
Best regards,

Joel Jacobson
Glue Finance

E: jj@gluefinance.com
T: +46 70 360 38 01

Postal address:
Glue Finance AB
Box  549
114 11  Stockholm
Sweden

Visiting address:
Glue Finance AB
Birger Jarlsgatan 14
114 34 Stockholm
Sweden

pgsql-hackers by date:

Previous
From: Marko Tiikkaja
Date:
Subject: Re: Avoiding deadlocks ...
Next
From: "Joshua D. Drake"
Date:
Subject: Re: git: uh-oh