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: type Stmt struct reused bug #8376
Labels
Comments
Comment 1 by beyondmj0.student@sina.com: http://golang.org/src/pkg/database/sql/sql.go: 1336 var cs connStmt 1337 match := false 1338 for i := 0; i < len(s.css); i++ { 1339 v := s.css[i] 1340 _, err := s.db.connIfFree(v.dc) 1341 if err == nil { 1342 match = true 1343 cs = v 1344 break 1345 } 1346 if err == errConnClosed { 1347 // Lazily remove dead conn from our freelist. 1348 s.css[i] = s.css[len(s.css)-1] 1349 s.css = s.css[:len(s.css)-1] 1350 i-- 1351 } 1352 1353 } 1354 s.mu.Unlock() 1355 1356 // Make a new conn if all are busy. 1357 // TODO(bradfitz): or wait for one? make configurable later? 1358 if !match { 1359 dc, err := s.db.conn() 1360 if err != nil { 1361 return nil, nil, nil, err 1362 } 1363 dc.Lock() 1364 si, err := dc.prepareLocked(s.query) 1365 dc.Unlock() 1366 if err != nil { 1367 s.db.putConn(dc, err) 1368 return nil, nil, nil, err 1369 } 1370 s.mu.Lock() 1371 cs = connStmt{dc, si} 1372 s.css = append(s.css, cs) 1373 s.mu.Unlock() 1374 } |
Comment 3 by marty.woodlee@mapmyfitnessinc.com: We are experiencing similar problems and came to the same conclusion regarding the root cause before finding this issue. Here's a proposal for a solution. I've compiled code against this and been able to get rid of the excessive statement preparation and memory leakage that was occurring otherwise: @@ -1360,17 +1360,27 @@ func (s *Stmt) connStmt() (ci *driverConn, releaseConn func(error), si driver.St if err != nil { return nil, nil, nil, err } - dc.Lock() - si, err := dc.prepareLocked(s.query) - dc.Unlock() - if err != nil { - s.db.putConn(dc, err) - return nil, nil, nil, err + alreadyPrepared := false + for _, v := range s.css { + if v.dc == dc { + alreadyPrepared = true + cs = v + break + } + } + if alreadyPrepared == false { + dc.Lock() + si, err := dc.prepareLocked(s.query) + dc.Unlock() + if err != nil { + s.db.putConn(dc, err) + return nil, nil, nil, err + } + s.mu.Lock() + cs = connStmt{dc, si} + s.css = append(s.css, cs) + s.mu.Unlock() } - s.mu.Lock() - cs = connStmt{dc, si} - s.css = append(s.css, cs) - s.mu.Unlock() } conn := cs.dc |
Comment 4 by marko@joh.to: This should be fixed in Go 1.4 by fdb52a28028a. |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
by beyondmj0.student@sina.com:
The text was updated successfully, but these errors were encountered: