Closed nklaassen closed 2 months ago
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Looks like this code was introduced in https://github.com/golang/go/commit/190d0d3e69b113bea0b6b604ba2f0beb62c08741 by @bradfitz
cc @bradfitz @kardianos @kevinburke
Change https://go.dev/cl/607238 mentions this issue: database/sql: fix panic with concurrent Conn and Close
Update: I managed to reproduce the panic very reliably in the go playground using only exported methods https://go.dev/play/p/fHZFq6zgAV4
@cherrymui, this probably warrants a backport to the 1.23 branch.
@gopherbot please backport this to Go 1.23. This is a regression in 1.23. Thanks.
Backport issue(s) opened: #69041 (for 1.23).
Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.
Change https://go.dev/cl/609255 mentions this issue: [release-branch.go1.23] database/sql: fix panic with concurrent Conn and Close
Go version
go version go1.23.0 darwin/arm64
Output of
go env
in your module/workspace:What did you do?
One of our unit tests seems to start a transaction concurrently with closing the database, this sometimes causes a panic here: https://github.com/golang/go/blob/a4cb37d4afd4b6b386ed7b51466c8c57c6045f9c/src/database/sql/sql.go#L3644
I haven't been able to reproduce this with
db.Conn
db.Close
calls yet, but I do have a unit test in https://github.com/golang/go/pull/68953 usingdatabase/sql.(*connRequestSet).CloseAndRemoveAll
anddatabase/sql.(*connRequestSet).Delete
that reliably reproduces the panic.Update: reproduced with exported methods on
database/sql.DB
here: https://go.dev/play/p/fHZFq6zgAV4What did you see happen?
This looks like a race condition in
database/sql.(*DB).conn
:(*DB).conn
heredelHandle
is set to the result ofdb.connRequests.Add(req)
, and thendb.mu
is unlockeddb.Close
will calldb.connRequests.CloseAndRemoveAll
here(*DB).conn
re-locksdb.mu
here and callsdb.connRequests.Delete(delHandle)
delHandle.idx
is positive and no bounds checking is done before trying to index into the slice which was set tonil
by(*connRequestSet).CloseAndRemoveAll
, resulting in the panic.Here's a full stack trace (from https://github.com/gravitational/teleport/actions/runs/10427126860/job/28881284822):
What did you expect to see?
I expected no panic.
sql.DB
is advertised as "safe for concurrent use by multiple goroutines"