“...I've been working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix and learning Rust. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working for InPay...”

Rob Lacey (contact@robl.me)
Senior Software Engineer, Brighton, UK

MySQL, Updates with Joins and clearing annoying locks

mysql> UPDATE logs LEFT JOIN ip_ranges ON logs.ip_int BETWEEN ip_ranges.start_ip AND ip_ranges.end_ip SET logs.country = ip_ranges.country_code WHERE logs.country IS NULL;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> show open tables where in_use>0;
+-----------------------------------+---------------+--------+-------------+
| Database                          | Table         | In_use | Name_locked |
+-----------------------------------+---------------+--------+-------------+
| production | logs |      2 |           0 |
| production | ip_ranges     |      2 |           0 |
+-----------------------------------+---------------+--------+-------------+
2 rows in set (0.00 sec)

mysql> show processlist;
+----+------+-----------+-----------------------------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
| Id | User | Host      | db                                | Command | Time | State        | Info                                                                                                 |
+----+------+-----------+-----------------------------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
|  1 | root | localhost |production | Sleep   |   14 |              | NULL                                                                                                 |
|  4 | root | localhost | production | Query   | 3857 | Sending data | SELECT COUNT(*) FROM `download_logs` JOIN ip_ranges ON ip_int BETWEEN ip_ranges.start_ip AND ip_rang |
|  5 | root | localhost | production | Query   | 3563 | Sending data | UPDATE `logs` JOIN ip_ranges ON ip_int BETWEEN ip_ranges.start_ip AND ip_ranges.end_ip SET  |
|  8 | root | localhost | production | Query   |    0 | init         | show processlist                                                                                     |
+----+------+-----------+-----------------------------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
4 rows in set (0.00 sec)

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

mysql> show processlist;
+----+------+-----------+-----------------------------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
| Id | User | Host      | db                                | Command | Time | State        | Info                                                                                                 |
+----+------+-----------+-----------------------------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
|  1 | root | localhost | production | Sleep   |   46 |              | NULL                                                                                                 |
|  5 | root | localhost | production | Query   | 3595 | Sending data | UPDATE `download_logs` JOIN ip_ranges ON ip_int BETWEEN ip_ranges.start_ip AND ip_ranges.end_ip SET  |
|  8 | root | localhost | production | Query   |    0 | init         | show processlist                                                                                     |
+----+------+-----------+-----------------------------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

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

mysql> show processlist;
+----+------+-----------+-----------------------------------+---------+------+-------+------------------+
| Id | User | Host      | db                                | Command | Time | State | Info             |
+----+------+-----------+-----------------------------------+---------+------+-------+------------------+
|  1 | root | localhost | production | Sleep   |   59 |       | NULL             |
|  8 | root | localhost | production | Query   |    0 | init  | show processlist |
+----+------+-----------+-----------------------------------+---------+------+-------+------------------+
2 rows in set (0.00 sec)

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

mysql> show processlist;
+----+------+-----------+-----------------------------------+---------+------+-------+------------------+
| Id | User | Host      | db                                | Command | Time | State | Info             |
+----+------+-----------+-----------------------------------+---------+------+-------+------------------+
|  8 | root | localhost | production | Query   |    0 | init  | show processlist |
+----+------+-----------+-----------------------------------+---------+------+-------+------------------+
1 row in set (0.00 sec)

mysql> UPDATE logs LEFT JOIN ip_ranges ON logs.ip_int BETWEEN ip_ranges.start_ip AND ip_ranges.end_ip SET logs.country = ip_ranges.country_code WHERE logs.country IS NULL;