Skip to content

Whackamole queries when KILL'ing #295

Closed
@xaprb

Description

@xaprb

Using the following code,

package main

import (
   "database/sql"
   _ "github.com/go-sql-driver/mysql"
   "log"
)

func main() {
   db, err := sql.Open("mysql", "root:@tcp(:12830)/")
   if err != nil {
      log.Fatal(err)
   }
   defer db.Close()

   var s string
   err = db.QueryRow("SELECT SLEEP(300)").Scan(&s)
   if err != nil {
      log.Fatal(err)
   }
   log.Println(s)
}

And running it, I can see in MySQL,

mysql> show full processlist;
+----+------+-----------------+------+---------+------+------------+-----------------------+
| Id | User | Host            | db   | Command | Time | State      | Info                  |
+----+------+-----------------+------+---------+------+------------+-----------------------+
| 95 | root | ::1:62318       | NULL | Query   |    0 | init       | show full processlist |
| 96 | root | 127.0.0.1:62446 | NULL | Query   |    7 | User sleep | SELECT SLEEP(300)     |
+----+------+-----------------+------+---------+------+------------+-----------------------+
2 rows in set (0.00 sec)

mysql> kill query 96;
Query OK, 0 rows affected (0.00 sec)

mysql> show full processlist;
+----+------+-----------+------+---------+------+-------+-----------------------+
| Id | User | Host      | db   | Command | Time | State | Info                  |
+----+------+-----------+------+---------+------+-------+-----------------------+
| 95 | root | ::1:62318 | NULL | Query   |    0 | init  | show full processlist |
+----+------+-----------+------+---------+------+-------+-----------------------+
1 row in set (0.00 sec)

The program prints out this:

2014/12/17 16:32:34 1

Now, if instead I kill the connection,

mysql> show full processlist;
+----+------+-----------------+------+---------+------+------------+-----------------------+
| Id | User | Host            | db   | Command | Time | State      | Info                  |
+----+------+-----------------+------+---------+------+------------+-----------------------+
| 95 | root | ::1:62318       | NULL | Query   |    0 | init       | show full processlist |
| 97 | root | 127.0.0.1:62452 | NULL | Query   |    5 | User sleep | SELECT SLEEP(300)     |
+----+------+-----------------+------+---------+------+------------+-----------------------+
2 rows in set (0.00 sec)

mysql> kill 97;
Query OK, 0 rows affected (0.00 sec)

mysql> show full processlist;
+----+------+-----------------+------+---------+------+------------+-----------------------+
| Id | User | Host            | db   | Command | Time | State      | Info                  |
+----+------+-----------------+------+---------+------+------------+-----------------------+
| 95 | root | ::1:62318       | NULL | Query   |    0 | init       | show full processlist |
| 98 | root | 127.0.0.1:62454 | NULL | Query   |    3 | User sleep | SELECT SLEEP(300)     |
+----+------+-----------------+------+---------+------+------------+-----------------------+
2 rows in set (0.00 sec)

So the statement got retried. This is, of course, because the connection got killed and the driver returned the error ErrBadConn. The program prints out:

[MySQL] 2014/12/17 16:35:41 packets.go:32: unexpected EOF

From the docs,

To prevent duplicate operations, ErrBadConn should NOT be returned if there's a possibility that the database server might have performed the operation. Even if the server sends back an error, you shouldn't return ErrBadConn.

What's happening here is that the query is a little bit unkillable if you kill the connection. It'll retry up to 10 times.

Is there any way we can detect that there was a kill? Given #185 I think the answer is "no" but I thought I should ask here anyway. From the client's point of view I think a KILL does look just like the connection was closed for some reason.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions