Locks & Trage queries
Hoe kun je MySQL locks herkennen en hoe ga je hiermee om.
We gaan er bij dit artikel vanuit dat je het mysql commando geconfigureerd hebt uitgelegd in artikel MySQL onder het kopje "Command line".
Locks
Voor het inzien van innodb locks wordt de query SHOW ENGINE INNODB STATUS
gebruikt. Deze is om security redenenen
niet direct toegankelijk maar via een alias command.
innodbstatus
*************************** 1. row ***************************
Type: InnoDB
Name:
Status:
=====================================
2020-02-06 19:55:44 7f62cab21700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 30 seconds
-----------------
BACKGROUND THREAD
-----------------
...
...
...
----------------------------
END OF INNODB MONITOR OUTPUT
============================
Dit commando is handig om huidige locks in te zien en de queries waar deze locks vandaan komen. In het geval van een cluster moet je dit commando uitvoeren op de database server. Dit kun je doen door een normale SSH user aan te maken op die server en zo in te loggen.
Lopende queries
MySQL doet om verschillende redenenen een lock op een row, tabel of zelfs een gehele database. Deze locks worden altijd verzoorzaakt door lopende query een query.
Je kunt met het mysql commando de lopende queries zien en naar wens stoppen.
Bijvoorbeeld:
mysql -e 'SHOW PROCESSLIST'
+----------+-----------+-------------------+---------------+---------+------+-------+------------------+-----------+---------------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined |
+----------+-----------+-------------------+---------------+---------+------+-------+------------------+-----------+---------------+
| 70569602 | shop_root | 192.168.0.2:45016 | shop_database | Sleep | 186 | | NULL | 1239 | 6782 |
| 70600067 | shop_root | 192.168.0.2:17014 | shop_database | Sleep | 61 | | NULL | 6 | 12 |
| 70600999 | shop_root | 192.168.0.4:39104 | shop_database | Sleep | 58 | | NULL | 0 | 0 |
| 70601002 | shop_root | 192.168.0.5:44738 | shop_database | Sleep | 32 | | NULL | 0 | 0 |
| 70601003 | shop_root | 192.168.0.5:44748 | shop_database | Sleep | 32 | | NULL | 0 | 0 |
| 70601019 | shop_root | 192.168.0.4:39184 | shop_database | Sleep | 9 | | NULL | 0 | 0 |
| 70601044 | shop_root | 192.168.0.2:20268 | shop_database | Sleep | 8 | | NULL | 0 | 0 |
| 70601053 | shop_root | 192.168.0.2:20308 | shop_database | Sleep | 8 | | NULL | 0 | 0 |
| 70601073 | shop_root | 192.168.0.4:39322 | shop_database | Sleep | 7 | | NULL | 0 | 0 |
| 70601097 | shop_root | 192.168.0.5:45000 | shop_database | Sleep | 7 | | NULL | 0 | 0 |
| 70601114 | shop_root | 192.168.0.2:20522 | shop_database | Sleep | 6 | | NULL | 0 | 0 |
| 70601154 | shop_root | 192.168.0.5:45190 | shop_database | Sleep | 5 | | NULL | 0 | 0 |
| 70601173 | shop_root | 192.168.0.4:39504 | shop_database | Sleep | 5 | | NULL | 0 | 0 |
+----------+-----------+-------------------+---------------+---------+------+-------+------------------+-----------+---------------+
38 rows in set (0.00 sec)
Hier zien we dat de query met id 70569602
al 186 seconden loopt. Dat is natuurlijk veel te lang en omdat er nog een paar
queries zijn welke al relatief lang bezig zijn lijkt het er op dat deze opgehouden worden door die query.
Een query killen gaat met een KILL
query:
mysql -e 'KILL 70569602'
Kill all
Als het nodig is om alles te stoppen en je geen tijd hebt om uit te zoeken welke query de boosdoener is kun je gebruik maken van dit commando:
mysql -e 'SHOW PROCESSLIST' | awk '$1 ~ /^[0-9]/ {print "KILL "$1";"}' | mysql