-
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: set maximum lifetime of connection #9851
Comments
It would be great to see this! |
An alternative would be to add an optional interface to database/sql/driver for checking liveness of a connection. That would give the driver more constraints and allow the go std library more freedom when to actually check this (e.g. via small batches or on prepare). |
I'm not saying this is a good solution, but as a workaround, couldn't you just return ErrBadConn from the driver if you notice the connection has been sitting idle for a long time? |
@johto Yes, I can. But it should be done carefully since hardcoded |
Yeah, but if the conn is known dead anyways, the behavior is ultimately the same. |
I'm thinking, sql.DB are hiding connection of driver intentionally. So RDBMS-specific problems should be resolved in the driver-side interface. https://github.com/mattn/go-sqlite3/blob/master/_example/hook/hook.go#L13-L18 This is not beautiful but works pretty good. |
Problems? Yeah, probably. But enforcing connection lifetimes isn't a database-specific problem.
This, to me, seems ugly beyond any recognition. For example, how do you make sure that the connection isn't handed out by database/sql while you're working on the underlying driver-specific handle? I think the proper solution would start out something like this: https://groups.google.com/d/topic/golang-dev/RWmOv4SYUmc/discussion |
You can't do it because go's driver have connection pool. So we can't know which connection is working for the current query. |
Can't do what exactly? And that's my point; we need something to pull a connection out of the pool, and then expose the driver interface beneath that connection. |
Yes, go hides native-driver interfaces to support any RDBCS, and to do not depend on the specific DB, I think. |
@mattn It's hard to clean expired connections from freelist in DB from driver's side. I don't know other RDBs have problems similar to MySQL or not. |
Yeah, exactly. Essentially, the gap between MaxOpenConns and MaxIdleConns right now is closed immediately if the connections go idle, i.e. there's a timeout of 0. What I'd like to see is something which only starts closing idle connections after a non-zero timeout. So if you want to enforce that no client is kept around idle for more than one minute, you could do:
If the reuse timeout defaults to 0, the interface stays backwards compatible in a nice way. |
Here is rough draft: https://gist.github.com/methane/6e77daac5a8c205ac359 There are some points remaining that I should decide before post it to gerrit.
|
Ah, you are talking about timeout that is implemented on go. I was confused something what mysql-lib doing that. sorry. |
I've send patch to gerrint; https://go-review.googlesource.com/6580 |
CL https://golang.org/cl/6580 mentions this issue. |
@methane Are we sure that this feature is doing the right thing? The linked MySQL docs for wait_timeout say:
The docs for the MySQL server has gone away error use similar language.
Perhaps not authoritative, but certainly more explicit, this MySQL DBA's blog says (near the bottom):
All of the evidence I can find indicates that MySQL closes connections that have not run a query for a number of seconds. I can find no evidence that the timeout is measured from when the connection was created as the initial feature request and CL 6580 describe. |
I'm sorry. I was wrong about wait_timeout. But still there are some cases old connections should be killed.
Killing not recently used connections doesn't solve such cases. |
I had the same problem when I was using JDBC - DBCP. DBCP allows me to specify a dummy query and the interval to run against the database. I set it to 1 hour so that there's no connection that could be idle for longer than 1 hour. |
@bradfitz, please review CL 6580 soon. Thanks. |
@bradfitz Is there any time configuration for no-interaction? |
"lifetime starting from no-interaction" < "lifetime starting from created" SetConnMaxLifetime can be used to solve many problems. And I don't want to add more timeouts Is there any reason you can't use SetConnMaxLifetime? |
@methane I don't think in other words,i want to keep socket lifetime(starting from created) as long as possible for efficient reuse of socket.And at the same time,i want to set socket lifetime(starting from no-interaction) only 30s for recycling the |
Before SetConnMaxLifetime, people tries to reduce idle connection via SetMaxIdleConns(). Thanks to SetConnMaxLifetime, reconnection rate changed from "dozen /secs" to "few /minutes". Now I'm not sure adding SetMaxIdleTimeout() improve efficiency dramatically. Is there good benchmark application which lack of SetMaxIdleTimeout cause major efficiency issue? |
MySQL has wait timeout option. It limits sum of idle time.
If
wait_timeout=3600
, client should not use connection created before one hour ago.Otherwise, connection may be killed while transaction.
Additionally, MySQL's global configuration is applied to only new connections.
So I want control how long client reuse connection. But
sql.DB
doesn't support limiting connection's lifetime.May I send patch that adds
DB.SetMaxReuseTimeout(time.Duration)
?Is there any plan to add more general way to customize behavior of connection pool?
(This may be related to #4805)
The text was updated successfully, but these errors were encountered: