Hé les gars, il est possible de faire un timeout dans MySQL? Ainsi, si une requête dépasse ce délai, elle sera supprimée par MySQL et renverra une erreur au lieu d'attendre l'éternité.
Réponses
Trop de publicités?Il y a une belle script Perl sur CPAN pour faire juste cela: http://search.cpan.org/~rsoliv/mysql-génocide-0.03/mysql-génocide
On a seulement besoin de planifier pour l'exécuter avec les paramètres appropriés. Créer un fichier CRONtab /etc/cron.d/mysql_query_timeout le programmer pour qu'il exécute toutes les minutes:
* * * * * root /path/to/mysql-genocide -t 7200 -s -K
Où 7200 est le maximum autorisé temps d'exécution en secondes. Le commutateur-s filtre tous sauf les requêtes SELECT. Le commutateur-K indique le script pour tuer le processus d'appariement.
La racine de l'utilisateur doit être en mesure d'exécuter mysql local des outils, sans authentification, sinon vous devrez fournir des informations d'identification sur la ligne de commande.
Je viens de configurer le script bash suivant en tant que tâche cron pour accomplir cela avec MySQL 5.0 (supprime toute requête exécutée depuis plus de 30 secondes). Partage ici au cas où cela s'avérerait utile à quiconque (désolé si mon style de script bash est inefficace ou atroce, ce n'est pas mon langage de développement principal):
#!/bin/bash
linecount=0
processes=$(echo "show processlist" | mysql -uroot -ppassword)
oldIfs=$IFS
IFS='
'
echo "Checking for slow MySQL queries..."
for line in $processes
do
if [ "$linecount" -gt 0 ]
then
pid=$(echo "$line" | cut -f1)
length=$(echo "$line" | cut -f6)
query=$(echo "$line" | cut -f8)
#Id User Host db Command Time State Info
if [ "$length" -gt 30 ]
then
#echo "$pid = $length"
echo "WARNING: Killing query with pid=$pid with total execution time of $length seconds! (query=$query)"
killoutput=$(echo "kill query $pid" | mysql -uroot -ppassword)
echo "Result of killing $pid: $killoutput"
fi
fi
linecount=`expr $linecount + 1`
done
IFS=$oldIfs
Je pensais que ça faisait un peu plus longtemps, mais selon cela ,
MySQL 5.7.4 permet de définir des délais d’exécution côté serveur, spécifiés en millisecondes, pour les instructions SELECT en lecture seule de niveau supérieur.
SELECT
MAX_STATEMENT_TIME = 1000 --in milliseconds
*
FROM table;
Notez que cela ne fonctionne que pour les instructions SELECT en lecture seule.
Depuis MySQL 5.1, vous pouvez créer une procédure stockée pour interroger la table information_schmea.PROCESSLIST pour toutes les requêtes correspondant à vos critères de "longue durée", puis parcourez un curseur pour les tuer. Configurez ensuite cette procédure pour qu'elle s'exécute de manière récurrente dans le planificateur d'événements.
Le forum MySQL a quelques discussions à ce sujet.
Cet article explique comment configurer les délais d'attente sur le serveur à l'aide de innodb_lock_wait_timeout.
Voici une façon de le faire par programme , en supposant que vous utilisez JDBC.