Open nishaad78 opened 5 years ago
After investigation, we found that the connStmt
func never finds the connection the prepare
command was sent on because db.conn
func that it is calling is implemented as a LIFO, meaning that the connection just used for prepare
will be the last one returned if nothing else happened in between prepare
and execute
.
ref: https://github.com/golang/go/blob/master/src/database/sql/sql.go#L2461-L2478
We tested this hypothesis by implementing a function that iterated over DB.freeConn
and Stmt.css
to find a match. This fixed this issue and we will open a PR.
Change https://golang.org/cl/179298 mentions this issue: database/sql: run prepare & execute commands on the same conn from DB pool
@nishaad78 I can review the CL for your for Go1.14 (we are still in a freeze for 1.13).
For your use case, have you considered using a dedicated Conn() and calling prepare and execute on a single Conn?
Yes, we are going to switch to a dedicated connection for our use case. However, we still think this behaviour should be fixed without having to use one since Prepare() can be run on the DB pool.
From: Daniel Theophanes notifications@github.com Sent: Thursday, May 30, 2019 2:31:57 AM To: golang/go Cc: Nishaad Ajani; Mention Subject: Re: [golang/go] database/sql: prepare command is always sent again when executing a statement on a DB pool with multiple open connections (#32298)
@nishaad78https://github.com/nishaad78 I can review the CL for your for Go1.14 (we are still in a freeze for 1.13).
For your use case, have you considered using a dedicated Conn() and calling prepare and execute on a single Conn?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/golang/go/issues/32298?email_source=notifications&email_token=AB7ZYNLVOXQTWMVKIXYSYTTPX3DZ3A5CNFSM4HQI6NUKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWQHQ2Q#issuecomment-497055850, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AB7ZYNIYC6ADB3BHBAOSUWTPX3DZ3ANCNFSM4HQI6NUA.
@kardianos could this qualify for a minor for 1.12?
@nishaad78 Assuming it is merged, no, it would (still) not qualify for a minor point release.
Please test scalability on large (64+ cores) machine.
See https://github.com/golang/go/issues/9484 and https://go-review.googlesource.com/c/go/+/2207/
@nishaad78 I'm glad you choose to move to a dedicated connection.
Of the entire sql package code base, I find the statement sub-pools the most challenging. Your CL may be fine, but I highly doubt I will be able to merge or maintain it.
EDIT: To be clear, unless a simpler, very straightforward solution is presented, this will likely be declined.
What did you do?
Executing a prepared sql query on a DB connection pool with at least 2 open connections always sends the
Prepare
command on two connections.For reproducing the error, first enable general logging in your MySQL DB:
Now, connect to your mysql DB:
Then run some concurrent sql commands to make sure the pool has more than one open connection:
Now that we have at least two open connections, run a prepare and execute command on the DB:
What did you expect to see?
What did you see instead?
System details