{"action":"created","issue":{"url":"https://api.github.com/repos/didi/gendry/issues/29","repository_url":"https://api.github.com/repos/didi/gendry","labels_url":"https://api.github.com/repos/didi/gendry/issues/29/labels{/name}","comments_url":"https://api.github.com/repos/didi/gendry/issues/29/comments","events_url":"https://api.github.com/repos/didi/gendry/issues/29/events","html_url":"https://github.com/didi/gendry/issues/29","id":385726526,"node_id":"MDU6SXNzdWUzODU3MjY1MjY=","number":29,"title":"about manager.Open","user":{"login":"zplzpl","id":7931755,"node_id":"MDQ6VXNlcjc5MzE3NTU=","avatar_url":"https://avatars0.githubusercontent.com/u/7931755?v=4","gravatar_id":"","url":"https://api.github.com/users/zplzpl","html_url":"https://github.com/zplzpl","followers_url":"https://api.github.com/users/zplzpl/followers","following_url":"https://api.github.com/users/zplzpl/following{/other_user}","gists_url":"https://api.github.com/users/zplzpl/gists{/gist_id}","starred_url":"https://api.github.com/users/zplzpl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zplzpl/subscriptions","organizations_url":"https://api.github.com/users/zplzpl/orgs","repos_url":"https://api.github.com/users/zplzpl/repos","events_url":"https://api.github.com/users/zplzpl/events{/privacy}","received_events_url":"https://api.github.com/users/zplzpl/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-11-29T13:03:38Z","updated_at":"2018-12-03T10:50:27Z","closed_at":null,"author_association":"NONE","body":"简单点就是Open(true)会创建一个脱缰的野马，没有 max life time...，默认交互式超时为：30S，没有意外你会遇到 invalid connection\r\n\r\n建议\r\n1、Open(false)\r\n2、SetConnMaxLifetime\r\n3、Ping()\r\n"},"comment":{"url":"https://api.github.com/repos/didi/gendry/issues/comments/443668013","html_url":"https://github.com/didi/gendry/issues/29#issuecomment-443668013","issue_url":"https://api.github.com/repos/didi/gendry/issues/29","id":443668013,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0MzY2ODAxMw==","user":{"login":"caibirdme","id":8054803,"node_id":"MDQ6VXNlcjgwNTQ4MDM=","avatar_url":"https://avatars0.githubusercontent.com/u/8054803?v=4","gravatar_id":"","url":"https://api.github.com/users/caibirdme","html_url":"https://github.com/caibirdme","followers_url":"https://api.github.com/users/caibirdme/followers","following_url":"https://api.github.com/users/caibirdme/following{/other_user}","gists_url":"https://api.github.com/users/caibirdme/gists{/gist_id}","starred_url":"https://api.github.com/users/caibirdme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caibirdme/subscriptions","organizations_url":"https://api.github.com/users/caibirdme/orgs","repos_url":"https://api.github.com/users/caibirdme/repos","events_url":"https://api.github.com/users/caibirdme/events{/privacy}","received_events_url":"https://api.github.com/users/caibirdme/received_events","type":"User","site_admin":false},"created_at":"2018-12-03T10:50:27Z","updated_at":"2018-12-03T10:50:27Z","author_association":"MEMBER","body":"首先，根据[官方文档](https://golang.google.cn/pkg/database/sql/#Open)：\r\n```\r\nOpen may just validate its arguments without creating a connection to the database. \r\nTo verify that the data source name is valid, call Ping.\r\n```\r\nOpen只是创建了一个内存中的结构体，只有Ping方法才会去检测你的连接设置是否正确（当然这意味着会新建一个连接）。这种检测是有必要的，因为数据库如果根本连不上的话，业务逻辑就完全没法处理，应该及早panic或者做其它处理。详见[这个issue](https://github.com/go-sql-driver/mysql/issues/82#issuecomment-18295777)\r\n\r\n其次，如果你新设置了MaxLifetime为d，d秒过后之前的连接就**可能**被清理掉。由于连接池也只会定期清掉一些`空闲的`过期的连接，换句话说，即使你设置了MaxLifetime，也不能保证所有连接都在有效期内，[源码](https://golang.google.cn/src/database/sql/sql.go?s=20363:20420#L910)：\r\n```\r\n\t\texpiredSince := nowFunc().Add(-d)\r\n\t\tvar closing []*driverConn\r\n\t\tfor i := 0; i < len(db.freeConn); i++ {\r\n\t\t\tc := db.freeConn[i]\r\n\t\t\tif c.createdAt.Before(expiredSince) {\r\n\t\t\t\tclosing = append(closing, c)\r\n\t\t\t\tlast := len(db.freeConn) - 1\r\n\t\t\t\tdb.freeConn[i] = db.freeConn[last]\r\n\t\t\t\tdb.freeConn[last] = nil\r\n\t\t\t\tdb.freeConn = db.freeConn[:last]\r\n\t\t\t\ti--\r\n\t\t\t}\r\n\t\t}\r\n\t\tdb.maxLifetimeClosed += int64(len(closing))\r\n\t\tdb.mu.Unlock()\r\n\r\n\t\tfor _, c := range closing {\r\n\t\t\tc.Close()\r\n\t\t}\r\n```\r\n在高负载的情况下，使用完的连接通常不会放入freeConn队列中，而是直接交给下一个请求使用了。所以很可能你使用的连接早就过了maxLifetime了。\r\n\r\n而连接本身被对端关闭或者信道出问题这种情况在任何时候都会出现，不会因为你设置了什么参数就可以避免的，如果有可能你需要自己去处理这些error"}}
{"actor":{"display_login":"caibirdme"}}