Kill MySQL query on user abort

If the time taken by query is because of the large dataset returned, then you can use mysql_unbuffered_query. And then in shutdown_function you can free the result and disconnect form mysql.

And if you are using PHP 5.3.x and have mysqlnd you can probably use MYSQLI_ASYNC in mysqli_query and then use mysqli_poll to get the result.

The first option will only help in case of time taken in retrieval of dataset. But if the mysql is actually taking a long time in parsing and creating the execution plan and loading tables to memory it wont help. In that case you need MYSQLI_ASYNC which is only available on PHP 5.3.x WITH mysqlnd.

Also if your main problem is session locking have a look at this post on PHP's documentation http://php.net/manual/en/ref.session.php#64525
You might find some helpful advice there.


Once PHP notices the user has stopped the request (this usually will not happen until the script tries to output something to the user), your script will terminate. Before shutting down, PHP calls any shutdown functions you've activated. You can implement a shutdown function that kills your query, and register it with register_shutdown_function()

An other way you might be able to do this, is by running your script with ignore_user_abort() turned on, and checking if the user has aborted by calling connection_aborted() periodically. If the user has aborted, kill the query and gracefully exit your script.

More information on connection handling here.


For those who are interested, here is what I used:

<?php
// Connection to query on
$query_con = mysqli_connect($host, $user, $password, $name, $port);

// Connection to kill on
$kill_con = mysqli_connect($host, $user, $password, $name, $port);

// Start the query
$query_con->query($slow_query, MYSQLI_ASYNC);

// Get the PID
$thread_id = $query_con->thread_id;

// Ignore user abort so we can kill the query
ignore_user_abort(true);

do  {
    // Poll MySQL
    $links = $errors = $reject = array($mysqli->mysqli);
    $poll = mysqli_poll($links, $errors, $reject, 0, 500000);

    // Check if the connection is aborted and the query was killed
    if (connection_aborted() && mysqli_kill($kill_con, $thread_id)) {
        die();
    }
} while (!$poll);

// Not aborted, so do stuff with the result
$result = $link->reap_async_query();
if (is_object($result)) {
    // Select
    while ($row = $result->fetch_object()) {
        var_dump($row);
    }
} else {
    // Insert/update/delete
    var_dump($result);
}

Tags:

Mysql

Php