-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
database/sql: deadlock on transaction stmt context cancel #40985
Comments
CC @kardianos |
Change https://golang.org/cl/250178 mentions this issue: |
Just had one possible solution by temporarily unlock |
Thank you for the reproduction. While I haven't looked too closely yet, the current CL may not be workable because it releases and re-acquires a lock. I greatly appreciate the test case that can reproduce this. |
Thank you for the reply. Maybe a better way is refactoring to reduce two locks around tx and stmt, though I still think re-check |
Hi I'm wondering if the fix is possible to backport to 1.14? |
@gopherbot @odeke-em Please consider this for backport to 1.15 and 1.14. |
Backport issue(s) opened: #42883 (for 1.14), #42884 (for 1.15). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases. |
Change https://golang.org/cl/284512 mentions this issue: |
Change https://golang.org/cl/284513 mentions this issue: |
Tx acquires tx.closemu W-lock and then acquires stmt.closemu.W-lock to fully close the transaction and associated prepared statement. Stmt query and execution run in reverse ways - acquires stmt.closemu.R-lock and then acquires tx.closemu.R-lock to grab tx connection, which may cause deadlock. Prevent the lock is held around tx.closePrepared to ensure no deadlock happens. Includes a test fix from CL 266097. Fixes #42884 Updates #40985 Updates #42259 Change-Id: Id52737660ada3cebdfff6efc23366cdc3224b8e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/250178 Run-TryBot: Emmanuel Odeke <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Daniel Theophanes <[email protected]> Trust: Emmanuel Odeke <[email protected]> (cherry picked from commit d4c1ad8) Reviewed-on: https://go-review.googlesource.com/c/go/+/284513 Reviewed-by: Dmitri Shuralyov <[email protected]>
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Not reproducible before Go 1.14.6.
I believe this issue is introduced by this CL: https://go-review.googlesource.com/c/go/+/216240/
And this issue: #39101
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Please try this test case:
What did you expect to see?
Should show up failed to execute transactions.
What did you see instead?
Process hang (deadlock).
Some analysis:
In CL https://go-review.googlesource.com/c/go/+/216240/ the
tx.closemu.Lock
is raised up beforetc.closePrepared
,which internally call statements closed, requires
stmt.closemu.Lock
.This path is triggered by context cancel.
On the other-hand, there's still an on-fly statement execution:
stmt.Exec
callsstmt.closemu.Rlock
until whole execution finished, internally it callstx.grabConn
and then acquiretx.closemu.Rlock
.Consider the case:
stmt.Exec
acquires thestmt.closemu.Rlock
first, but blocked bytx.closemu.Lock
due to transaction rollback, and for transaction rollback, after it acquires thetx.closemu
, it still can't make any progress due tostmt.closemu
is held bystmt.Exec
.Hence cause the deadlock.
The text was updated successfully, but these errors were encountered: