tiempo - ver peticiones mysql
¿Cómo puedo detener una consulta de MySQL si toma demasiado tiempo? (11)
A partir de MySQL 5.1, puede crear un procedimiento almacenado para consultar la tabla information_schmea.PROCESSLIST para todas las consultas que coincidan con sus criterios de "ejecución prolongada" y luego iterar sobre un cursor para eliminarlas. Luego, configure ese procedimiento para que se ejecute de forma recurrente en el programador de eventos.
¿Es posible suspender una consulta en MySQL?
Es decir, si alguna consulta excede el tiempo que especifico, MySQL la eliminará y devolverá un error en lugar de esperar por la eternidad.
Acabo de configurar el siguiente script bash como un trabajo cron para lograr esto con MySQL 5.0 (elimina cualquier consulta que se haya estado ejecutando durante más de 30 segundos). Compartirlo aquí en caso de que sea útil para alguien (disculpas si mi estilo de scripts de bash es ineficaz o atroz, no es mi lenguaje de desarrollo 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
Aquí está mi guión:
mysql -e ''show processlist/G'' |/
egrep -b5 ''Time: [6-9]{3,10}'' |/
grep ''Id:'' |/
cut -d'':'' -f2 |/
grep -v ''155'' |/ ## Binary Log PID
sed ''s/^ //'' |/
while read id
do
mysql -e "kill $id;"
done
Creo que esta vieja pregunta necesita una respuesta actualizada.
Puede establecer un tiempo de espera GLOBAL
para todas sus consultas SELECT
solo lectura como esta:
SET GLOBAL MAX_EXECUTION_TIME=1000;
El tiempo especificado es en milisegundos.
Si desea el tiempo de espera solo para una consulta específica, puede configurarlo en línea de esta manera:
SELECT /*+ MAX_EXECUTION_TIME(1000) */ my_column FROM my_table WHERE ...
MySQL devuelve un error en lugar de esperar por la eternidad.
Tenga en cuenta que este método solo funciona para SELECT
s de solo lectura. Si se determina que una declaración SELECT
no es de solo lectura, entonces cualquier temporizador configurado para ella se cancela y se informa al usuario del siguiente mensaje de NOTA:
Note 1908 Select is not a read only statement, disabling timer
Para declaraciones con subconsultas, limita la parte superior de SELECT
solamente. No se aplica a las instrucciones SELECT
dentro de los programas almacenados. Se MAX_EXECUTION_TIME
la utilización de la sugerencia MAX_EXECUTION_TIME
en las instrucciones SELECT
dentro de un programa almacenado.
Desde MySQL 5.7.8, existe la opción max_execution_time que define el tiempo de espera de ejecución para las sentencias SELECT.
El foro de MySQL tiene algunos hilos sobre esto.
Esta publicación detalla cómo configurar los tiempos de espera en el servidor usando innodb_lock_wait_timeout.
Aquí hay una manera de hacerlo mediante programación , asumiendo que está utilizando JDBC.
Hay un buen script de Perl en CPAN para hacer esto: http://search.cpan.org/~rsoliv/mysql-genocide-0.03/mysql-genocide
Solo hay que programarlo para que se ejecute con los parámetros adecuados. Cree un archivo CRONtab /etc/cron.d/mysql_query_timeout para programarlo para que se ejecute cada minuto:
* * * * * root /path/to/mysql-genocide -t 7200 -s -K
Donde 7200 es el tiempo de ejecución máximo permitido en segundos. El modificador -s filtra todas las consultas excepto SELECT. El conmutador -K le indica al script que elimine los procesos coincidentes.
El usuario root debería poder ejecutar las herramientas locales de mysql sin autenticación, de lo contrario, deberá proporcionar las credenciales en la línea de comandos.
Navicat lanzó recientemente su propia herramienta de monitoreo llamada Navicat Monitor . Cuenta con un analizador de consultas que proporciona información en tiempo real sobre sus consultas para mejorar rápidamente su rendimiento. Es una excelente manera de ver rápidamente cuántas y qué tipos de consultas están causando problemas.
Otra opción es la función Monitor del servidor. Se encuentra en todas las herramientas de administración de bases de datos de Navicat con la excepción de Navicat para SQLite.
Tiene una lista de procesos, que muestra todos los procesos en su base de datos. Allí, puede elegir el proceso de consulta para eliminar y hacer clic en el botón Finalizar proceso para detenerlo.
Robar
No creo que el egrep anterior encuentre "2000".
¿Por qué no intentas simplemente seleccionando el ID también, y evitando todas esas cosas de shell elegante:
mysql -e ''select id from information_schema.processlist where info is not null and time > 30;''
Para eliminar las consultas basadas en su thread_id, intente la consulta y elimínelas manualmente.
SELECCIONE ID DE INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = ''Query'' AND TIME> 10;
Un enfoque alternativo e interactivo sería enviar los valores a un archivo utilizando la consulta,
SELECT CONCAT(''KILL '',ID,'';'')
FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE USER = ‘new’
AND COMMAND = ''Query''
AND TIME > 10
INTO OUTFILE ''/tmp/thread_kill.txt'';
y luego matar los hilos en el archivo usando,
/. /tmp/thread_kill.txt
Otra alternativa es buscar herramientas de monitoreo como MONyog, MySQL Enterprise Monitor, kit de herramientas de Percona donde puede permitir que la herramienta busque las consultas más largas / lentas, bloquee las consultas y las elimine. Con MONyog la ventaja adicional es que las consultas lentas no solo pueden MONyog sino que también informan al usuario por correo electrónico acerca de qué consulta detuvo los recursos y redujo la velocidad del servidor.
Pensé que había existido un poco más, pero de acuerdo con this ,
MySQL 5.7.4 introduce la capacidad de establecer límites de tiempo de ejecución del lado del servidor, especificados en milisegundos, para las instrucciones SELECT de solo lectura de nivel superior.
SELECT
MAX_STATEMENT_TIME = 1000 --in milliseconds
*
FROM table;
Tenga en cuenta que esto solo funciona para sentencias SELECT de solo lectura.