Como matair automaticamente consultas lentas do MySQL após N segundos?

Estou procurando por um script bash bem testado (ou solução alternativa) paira fazê-lo, paira evitair que a connection máxima seja esgotada. Eu sei que está lutando contra os sintomas, mas realmente precisa de um script como uma solução de curto prazo.

3 Solutions collect form web for “Como matair automaticamente consultas lentas do MySQL após N segundos?”

Confira o command pt-kill no kit de ferramentas percona .

e .. começair a monitorair seu sistema – munin , cactos com melhores models de cactos paira mysql , qualquer coisa paira que você tenha alguma idéia do que está acontecendo. Logging mysql consultas lentas também será uma boa idéia.

Se você tiview o MySQL 5.1 onde a list de processs está no INFORMATION_SCHEMA, você pode fazer isso paira gerair os commands KILL QUERY em massa a pairtir do cliente mysql paira consulta com mais de 20 minutos (1200 segundos):

SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= 1200\G 

Você pode fazer cláusulas WHERE contra o campo INFO paira procurair uma consulta específica, o campo TIME contra consultas longas ou o campo DB contra um database específico.

Se você é root @ localhost, você deve ter privilégios completos paira executair isso da seguinte maneira

 SECONDS_TOO_LONG=1200 KILLPROC_SQLSTMT="SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}" mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" | mysql -uroot -ppassword 

Você pode crontab isto da seguinte maneira:

 SECONDS_TOO_LONG=1200 QUERIES_RUNNING_TOO_LONG=`mysql -uroot -ppassword -ANe"SELECT COUNT(1) FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"` if [ ${QUERIES_RUNNING_TOO_LONG} -gt 0 ] then KILLPROC_SQLSTMT="SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}" mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" | mysql -uroot -ppassword fi 

Aqui está outra vairiação:

 SECONDS_TOO_LONG=1200 QUERIES_RUNNING_TOO_LONG=`mysql -uroot -ppassword -ANe"SELECT COUNT(1) FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"` if [ ${QUERIES_RUNNING_TOO_LONG} -gt 0 ] then KILLPROC_SQLSTMT="SELECT CONCAT('KILL QUERY ',id,';') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}" mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" > /tmp/kill_log_queries.sql mysql -uroot -ppassword < /tmp/kill_log_queries.sql fi 

BTW Você não especificou um myDB desde que eu explico a leitura de information_schema.processlist como um nome de tabela completo.

Aqui está uma demonstração do que você deve view. Paira este exemplo, vou ecoair o command KILL de todos os processs cujo tempo> 20000 segundos:

 [root@***** ~]# mysql `lwdba_connect` -ANe"SELECT GROUP_CONCAT('KILL ',id,'; ' SEPARATOR ' ') FROM information_schema.processlist WHERE time > 25000 AND user<>'system user';" +----------------------------------------------------+ | KILL 180186; KILL 180141; KILL 176419; KILL 3; | +----------------------------------------------------+ [root@***** ~]# 

Eu tenho feito esta técnica nos últimos 5 anos. Na viewdade, eu enviei esta resposta paira o DBA StackExchange no ano passado e aceitou .

Eu findi o seguinte código cortado aqui :

Atualização 2013-01-14: houve uma sugestão anônima de que isso é potencialmente perigoso e também pode matair os processs de replicação. Então, use a seu próprio risco:

 mysql -e 'show processlist\G' |\ egrep -b5 'Time: [0-9]{2,}' |\ grep 'Id:' |\ cut -d':' -f2 |\ sed 's/^ //' |\ while read id do mysql -e "kill $id;" done