-
Notifications
You must be signed in to change notification settings - Fork 95
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
Using driver/sql hangs database and other oddities #210
Comments
Thank you for the detailed issue @tie! I don't think there should be a special case for the in-memory engine, but rather make sure that every instance of Concerning your proposals, I think they both make sense, I will look into them and try to propose a fix for the next release. |
This change allows driver implementations to manage resources in driver.Connector, e.g. to share the same underlying database handle between multiple connections. That is, it allows embedded databases with in-memory backends like SQLite and Genji to safely release the resources once the sql.DB is closed. This makes it possible to address oddities with in-memory stores in SQLite and Genji drivers without introducing too much complexity in the driver implementations. See also: - mattn/go-sqlite3#204 - mattn/go-sqlite3#511 - chaisql/chai#210
This change allows driver implementations to manage resources in driver.Connector, e.g. to share the same underlying database handle between multiple connections. That is, it allows embedded databases with in-memory backends like SQLite and Genji to safely release the resources once the sql.DB is closed. This makes it possible to address oddities with in-memory stores in SQLite and Genji drivers without introducing too much complexity in the driver implementations. See also: - mattn/go-sqlite3#204 - mattn/go-sqlite3#511 - chaisql/chai#210
This change allows driver implementations to manage resources in driver.Connector, e.g. to share the same underlying database handle between multiple connections. That is, it allows embedded databases with in-memory backends like SQLite and Genji to safely release the resources once the sql.DB is closed. This makes it possible to address oddities with in-memory stores in SQLite and Genji drivers without introducing too much complexity in the driver implementations. See also: - mattn/go-sqlite3#204 - mattn/go-sqlite3#511 - chaisql/chai#210 Fixes #41790 Change-Id: Idbd19763134438ed38288b9d44f16608e4e97fd7 GitHub-Last-Rev: 962c785 GitHub-Pull-Request: #41710 Reviewed-on: https://go-review.googlesource.com/c/go/+/258360 Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com> Reviewed-by: Daniel Theophanes <kardianos@gmail.com> Trust: Emmanuel Odeke <emmanuel@orijtech.com> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org>
I can reproduce mattn/go-sqlite3#204 with minimal changes.
main1.go
main2.go
I assume SQLite releases db locks when they are not needed. But this issue gets worse with Genji since BoltDB blocks on db lock (unless a timeout was specified, which is not currently possible with
sql/driver
), and BadgerDB I believe just returns an error. That is, things go terribly wrong whensql.DB
attempts to open a newsql.Conn
.As a temporary workaround it’s possible to call
SetMaxOpenConns(1)
on*sql.DB
from the user’s code. This should work just fine for in-memory and bolt engines, but afaik badger supports concurrent transactions whereas singledriver.Conn
can’t be used concurrently.I’ve experimented a bit with possible APIs to fix those issues, and I think the best option would be to fix this use case on the Go side by allowing
driver.Connector
to implement optionalio.Closer
interface and close it insql.DB.Close
. Thendriver.Connector
would be able to holdgenji.DB
object and release the resources whensql.DB
is no longer needed.Alternatively, it’s possible to do reference counting on
genji.DB
indriver.Connector
anddriver.Conn
, and have a special case for in-memory engines. That has a benefit of releasing the database handle when idle (e.g. so that other processes may perform some maintenance tasks).driver.Conn
is reusing itself asdriver.Tx
for transactions (lines 117–123). This won’t work as expected if we begin multiple transactions on a single connection.https://github.com/genjidb/genji/blob/112fd24e38b07590fd077be043837e0425731a8a/sql/driver/driver.go#L108-L124
The text was updated successfully, but these errors were encountered: