-
-
Notifications
You must be signed in to change notification settings - Fork 62
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
Closing database connection while query is still pending #132
Comments
Hi @LouisTSpi! Graceful closing of the connection requires sending a command to the server, which as you noticed needs to go into the queue. Cancelling a MySQL query requires issuing another query on a different connection, The other option is to abruptly close the socket connection, but this will leave the table in a metadata lock state again. I suspect the table is being left in a lock state because the close operation is not being allowed to complete before the script is terminated. Instead of using I'd recommend upgrading to v3 if you're able. The API is much cleaner and the use of fibers would have avoided the close issue, as the fiber will suspend until the connection closes. |
Hello @trowski, Thank you for your reply. I think I was not clear enough about the metadata lock state, let me rephrase to try and clear things up. For example the situation would be:
I'll try force closing the socket. As said above, since the table was already in the lock state before issuing the queries, it does not really matter if the table is left in the lock state afterwards. What matters is that the connection is closed, so that mysql can accept new connections to answer other queries (not all queries use the locked table).
I've tested an implementation using v3 beta but I get the same result. I'm considering migrating the production app once amphp/sql, amphp/sql-common and amphp/mysql are stable. As far as I can tell they are still in beta. |
Hello,
Using v2.1.3 of Amphp/Mysql, I need to execute queries on multiple db servers, with the following requirements:
The current implementation uses
Amp\Promise\timeout
to wrap the execution of each query, andAmpPromise\any
combinator to execute the promises in parallel:This will output
The only thing that is not working as expected is that when
$db->close
is called in the finally, it does not close the connection if a query is still pending.In this test case example with
SLEEP()
, the long query is still visible in mysqlSHOW FULL PROCESSLIST
, and after some time the connection is aborted andSHOW GLOBAL STATUS
'sAborted_clients
is incremented by 1.(In my practical case the issue is even worse because the table is in a metadata lock state so the query end up 'waiting for metadata lock', and the connection is never aborted: the query stays in queue until the lock is released, meanwhile other queries try to get connections to the db and in the end the server reaches 'Too many connections')
Looking into the internals of
Amphp\Mysql
, it seems the$db->close()
method ends up callingAmp\Mysql\Internal\Processor->sendClose()
which itself callsstartCommand()
with a callback to actually send the COM_QUIT signal to the server.startCommand
appends the task to the queue, but as the initial request is still pending, it seems the callback is never called and the connection is left open.Is there a way to force the connection to close even when there is a pending query?
Or is there something wrong with this implementation?
Thanks
The text was updated successfully, but these errors were encountered: