Skip to content

database/sql: prepared statements leak connections with high concurrency #5323

@snaury

Description

@snaury
When using database/sql with prepared statements and concurrency higher that
MaxIdleConns connections are leaked and recreated until database cannot accept anymore.
See https://groups.google.com/d/msg/golang-nuts/-YbB2Qjg41g/Afuaf8nSmGEJ for a related
discussion.

The problem is that all connections that have ever been used by Stmt are marked as
dependent on that Stmt, and that dependency is only removed when Stmt is closed. When
connection, that was over MaxIdleConns limit, is returned, it is not actually closed,
because it is still used by Stmt. Later, when Stmt tries to find a free connection, is
sees that connection is not free and doesn't use it. This causes database/sql to create
driver connections over and over again, until underlying database refuses and replies
with errors.

I think dependency should only be added in Stmt.connStmt and removed in releaseConn
callbacks, because prepared statements don't really appear to "use" the
connection, merely "cache" it. On the other hand such solution would mean that
drivers's Stmt.Close is never called.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions