MySQL Runaway Queries and KILL
`KILL QUERY` stops the statement and leaves the connection alive; `KILL` drops the whole connection and rolls back its transaction. The victim sees `ERROR 1317` and the difference between the two matters more than it sounds.
Troubleshooting Guide 37 of 45 Intermediate
- OSUbuntu 26.04 LTS (resolute)
- MySQL8.4.10-0ubuntu0.26.04.1
- Topologydb-a01 source, db-b01 and db-c01 replicas
- TimeAbout 13 min
- Reviewed27 August 2026
Written against the versions above. A killed statement rolls back, and rolling back a large transaction can take longer than the statement did. Killing is not always the fast option.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| db-a01 | 192.168.0.81 | Ubuntu 26.04 LTS | Primary / Source / Replica Set Member 1 | 2 Core | 4 GB | 50 GB |
Before you start
- The 400,000-row
eventstable from the performance track.
-
Start something expensive, find it, and stop it
A self-join of a 400,000-row table on a column with ten distinct values - each row matches roughly forty thousand others, so this is billions of comparisons. A realistic accident: a missing join condition or a forgotten filter.
The process list is searched by the statement's own text rather than by a guessed id, which is how you find the right connection when there are dozens.
INFOholds the running statement, soLIKEon it is a reliable way to identify a specific query.KILL QUERYstops the statement. The victim seesERROR 1317: Query execution was interrupted- an unmistakable message, distinct from a timeout or a syntax error, so a well-behaved application can log it as "cancelled" rather than "failed".The connection survives.
KILLwithoutQUERYwould have closed it entirely and rolled back any open transaction - which is what you want for a leaked connection and not what you want for an application mid-request.bash Example session sudo bash -c 'mysql appdb -e "SELECT COUNT(*) FROM events e1 JOIN events e2 ON e1.customer_id = e2.customer_id" >/tmp/runaway.out 2>&1 & sleep 3; ID=$(mysql -N -e "SELECT ID FROM information_schema.PROCESSLIST WHERE INFO LIKE \"%e1 JOIN events e2%\" LIMIT 1"); echo "runaway connection id: $ID"; mysql -e "KILL QUERY $ID"; sleep 1; cat /tmp/runaway.out; wait'runaway connection id: 97ERROR 1317 (70100) at line 1: Query execution was interruptedExpected resultThe connection id, then
ERROR 1317 (70100): Query execution was interrupted.Success conditionYou can stop one statement without dropping the connection running it.
-
Now use KILL without QUERY, and watch the difference
The same setup, but the target is inside an open transaction that has already updated a row - and this time the statement is bare
KILL.The victim sees
ERROR 2013: Lost connection to MySQL server during query, not 1317. That is a different failure entirely: 1317 says *your query was cancelled and you are still connected*; 2013 says *the connection is gone*. An application distinguishing them will retry one and reconnect for the other.The count afterwards is 0 - the connection is no longer in the process list. And because the connection closed with a transaction open, that transaction was rolled back: nothing it had done survives.
So the choice is about scope.
KILL QUERYfor a runaway statement on a connection you want to keep.KILLfor a leaked or hostile connection, accepting that its open work is discarded.bash Example session sudo bash -c 'mysql appdb -e "START TRANSACTION; UPDATE customers SET credit=credit+1 WHERE id=1; SELECT SLEEP(20);" >/tmp/k1.out 2>&1 & sleep 3; ID=$(mysql -N -e "SELECT ID FROM information_schema.PROCESSLIST WHERE INFO LIKE \"%SLEEP(20)%\" LIMIT 1"); echo "target id: $ID"; mysql -e "KILL $ID"; sleep 1; echo "--- victim saw ---"; cat /tmp/k1.out; echo "--- still connected? ---"; mysql -N -e "SELECT COUNT(*) FROM information_schema.PROCESSLIST WHERE ID = $ID"; wait'target id: 12--- victim saw ---ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during query--- still connected? ---0Expected result
ERROR 2013 (HY000): Lost connection to MySQL server during query, and a process-list count of 0 for that id.Success conditionYou can choose between cancelling a statement and closing a connection.
-
Confirm the row is intact
The row the killed transaction had updated, read back afterwards.
It holds a single consistent value. The killed transaction never committed, so InnoDB rolled its change back - the same mechanism the schema track demonstrated with an explicit
ROLLBACK, applied here because the connection died rather than because anyone asked.This is the guarantee that makes killing a connection a safe operation on a transactional engine. On a non-transactional one it would leave the row half-updated.
bash Example session sudo mysql --table appdb -e "SELECT id, credit FROM customers WHERE id = 1"+----+--------+| id | credit |+----+--------+| 1 | 126.50 |+----+--------+Expected resultOne row with a single consistent credit value.
Success conditionYou know a killed connection cannot leave a half-finished transaction.
Troubleshooting
KILLreturns immediately but the query keeps running.Why: The thread only notices the kill at certain points, and rollback takes time.
Fix:Watch
STATEin the process list.Rolling backmeans it is working - killing again does not help.Killing a long transaction made things worse.
Why: The rollback has to undo everything it did, holding locks the whole time.
Fix:For a long-running write, letting it finish is sometimes faster. Check
Innodb_rows_deletedor the rollback state before deciding.You killed the wrong connection.
Why: The id was read from a stale process list.
Fix:Match on
INFOrather than remembering an id. Ids are reused.ERROR 1095: You are not owner of thread.Why: Killing another account's connection needs
CONNECTION_ADMIN.Fix:Use an administrative account. Do not grant it to applications.