Développement et bases de données

Arrêter des requêtes MySQL en cours d'exécution

Vérifié le 6 min de lecture MySQL requêtes

Il arrive qu'une requête SQL prenne beaucoup plus de temps que prévu, à cause d'une erreur de l'application ou parce qu'elle est très lourde. Si, en plus, elle verrouille la table, les autres requêtes restent en attente et le site se bloque. Dans ce cas, vous pouvez arrêter la requête à la main.

Il y a deux façons de l'arrêter :

  • KILL QUERY id arrête seulement la requête et laisse la connexion ouverte. C'est l'option recommandée.
  • KILL id (et mysqladmin kill id) ferme toute la connexion, ce qui annule toute transaction en cours.

Depuis le terminal

Connectez-vous au compte en SSH. Si vous avez de l'expérience, utilisez le terminal de votre ordinateur ; sinon, le terminal intégré à cPanel est plus simple.

Avec des requêtes SQL

Connectez-vous à MySQL avec un utilisateur qui a des privilèges sur la base de données :

mysql -u usuario_mysql -p

Le mot de passe vous sera demandé. Ne le saisissez pas dans la commande elle-même (-pcontraseña), car il resterait dans l'historique du terminal.

Listez les processus ouverts :

SHOW FULL PROCESSLIST;

Vous verrez un tableau avec chaque connexion, son utilisateur, sa base de données, son état, le nombre de secondes écoulées (Time) et la requête (Info) :

Résultat de SHOW FULL PROCESSLIST avec les requêtes en cours d'exécution

Les lignes dont Command vaut Sleep sont des connexions inactives sans requête en cours : en général, inutile d'y toucher. Celle que vous cherchez a généralement un Time élevé et un état comme Sending data, Locked ou Waiting for table metadata lock.

Relevez la valeur de la colonne Id de la requête à arrêter et exécutez :

KILL QUERY 12345;

Exécutez de nouveau SHOW FULL PROCESSLIST; et vérifiez qu'elle n'apparaît plus. Si elle est toujours là avec l'état Killed, elle est en train d'annuler des modifications : patientez quelques secondes. Si elle ne se ferme toujours pas, fermez toute la connexion avec KILL 12345;.

Arrêter toutes les requêtes d'un utilisateur

Si de nombreuses requêtes du même utilisateur s'accumulent, cette requête génère les ordres pour toutes les arrêter. Remplacez USUARIO_MYSQL par l'utilisateur qui les exécute :

SELECT GROUP_CONCAT(CONCAT('KILL QUERY ', ID, ';') SEPARATOR ' ')
FROM information_schema.PROCESSLIST
WHERE USER = 'USUARIO_MYSQL'
  AND COMMAND <> 'Sleep'
  AND ID <> CONNECTION_ID();

Copiez le résultat (quelque chose comme KILL QUERY 101; KILL QUERY 102; ...), collez-le et exécutez-le. La condition ID <> CONNECTION_ID() évite d'arrêter votre propre session, et COMMAND <> 'Sleep' écarte les connexions inactives.

Pour n'arrêter que les requêtes qui contiennent un texte, par exemple celles qui portent sur une table, ajoutez un filtre supplémentaire :

  AND INFO LIKE '%wp_options%'

Sur l'hébergement, vous ne verrez et ne pourrez arrêter que les requêtes de vos propres utilisateurs MySQL.

Avec mysqladmin

Depuis le terminal, vous pouvez aussi utiliser mysqladmin sans vous connecter à MySQL. Listez les processus :

mysqladmin -u usuario_mysql -p processlist

Puis arrêtez celui que vous voulez avec son identifiant :

mysqladmin -u usuario_mysql -p kill 12345

Vous pouvez en indiquer plusieurs séparés par des virgules : kill 101,102,103. Gardez à l'esprit que mysqladmin kill ferme toute la connexion, pas seulement la requête.

Pour arrêter d'un coup toutes les requêtes contenant un texte (le nom d'une table, d'une base de données...), combinez la liste avec awk :

mysqladmin -u usuario_mysql -p processlist | awk -F'|' '/TEXTO_A_FILTRAR/ && $6 !~ /Sleep/ {gsub(/ /,"",$2); print $2}' | paste -sd, - | xargs -r mysqladmin -u usuario_mysql -p kill

La commande demande le mot de passe deux fois : une pour lister et une autre pour arrêter. Avant de la lancer, exécutez seulement la première partie (jusqu'à paste) pour voir quels identifiants elle va arrêter.

Depuis phpMyAdmin

Ouvrez phpMyAdmin, sélectionnez la base de données et ouvrez l'onglet SQL. Saisissez :

SHOW FULL PROCESSLIST;

phpMyAdmin affiche le tableau des processus avec un lien Tuer (Kill) à côté de chacun pour l'arrêter d'un clic :

Liste des processus dans phpMyAdmin avec l'option pour arrêter chaque requête

Vous trouverez aussi la même liste dans État > Processus. Le lien de phpMyAdmin ferme toute la connexion ; si vous voulez arrêter seulement la requête, saisissez KILL QUERY id; dans l'onglet SQL.

Si cela se reproduit

Arrêter la requête résout le blocage, mais pas sa cause. Si la même requête reste souvent bloquée, il manque généralement un index sur la table, ou une extension ou une tâche planifiée la lance trop souvent. Regardez le texte de la colonne Info pour savoir ce qui la génère.

Plus de détails dans la documentation de MySQL sur KILL.

Cela peut aussi vous aider

Quelque chose cloche ou a changé ? Racontez-nous et nous le vérifions.