Home » cPanel, Howto, Linux

HOWTO – Risolvere il problema delle query in sleep su mysql

5 gennaio 2008 964 views One Comment

E’ capitato molte volte di trovarsi di fronte a un problema serio su macchine in hosting e mysql installato.

Se ci sono siti progettati male (e, credetemi, ce ne sono!) molti programmatori non fanno attenzione ad ottimizzare le proprie query.

La situazione che si crea, è quella di trovarsi il load alto della macchina e, facendo un mysqladmin proc da root, ci troviamo di fronte una marea di query in sleep.

Ho aggirato il problema, facendo questo script che posto di seguito.

In pratica ad intervalli di tempo stabiliti (di default ogni 60 secondi) killa le query in sleep che sono, appunto, in sleep per più di 60 secondi.

Ma passiamo al codice.

File: mysql_sleep_query_kill.php

// Mysql sleep kill

//                     * coded by morphey (morphey@morphey.org)

//

// AVVISO: deve essere avviato via cron come utente "root" (uid=0)

// ottimizzato per cPanel

// Configurazione: ___________________________|

// $sleep_time = Impostare i secondi dopo i quali, se la query e' in sleep, si killera' automaticamente la query

$sleep_time = "60";

// $times = Impostare quante volte eseguire lo script | 0 = infinito (rimane in bg)

$times = 1;

// $times_sleep = Impostare quanto tempo far passare prima dell'avvio di un ciclo

$times_sleep = "1";

// $file_log = Impostare il file di log (percorso "assoluto" compreso) | sara' utilizzato per l'invio delle email

$file_log = "/var/log/mysql_kill_query.log";

$database_skip = array();

// $database_skip[] = Impostare i database da far saltare al controllo

$database_skip[] = "eximstats";

$database_skip[] = "horde";

//___________________________________|

function scriviLog($somecontent) {

global $file_log;

$filename = $file_log;

if (!is_file($filename)) { shell_exec("touch ".$filename." ; chmod 777 ".$filename); }

if (!is_writable($filename)) { shell_exec("chmod 777 ".$filename); }

$handle = fopen($filename, 'a');

fwrite($handle, $somecontent."\n");

fclose($handle);

}$active_times = 0;

while ($active_times<=$times) {

$out = shell_exec("mysqladmin proc");

$c = 0;

foreach (explode("\n",$out) as $linea) {

if (!eregi("-+-",$linea)) {

if ($c!=0) {

$arr = explode("|",trim($linea));

if ($arr[1]!="") {

$time = intval(ltrim(rtrim($arr[6])));

settype($time,"integer");

$id = ltrim(rtrim($arr[1]));

$user = ltrim(rtrim($arr[2]));

$database = ltrim(rtrim($arr[4]));

$command = ltrim(rtrim($arr[5]));

$state = ltrim(rtrim($arr[7]));

$query = ltrim(rtrim($arr[8]));

echo "ID->".$arr[1]." | Time->".$arr[6]." | User->".$arr[2]." | Query->".$query;

if ($time>=$sleep_time) {

$check_db = 0;

foreach ($database_skip as $db_skip) {

if ($database==$db_skip) { $check_db = 1; }

}

if ($check_db!=1) {

// struttura dei log

// id,user,database,command,state,times,query

scriviLog(date("d-m-Y_G.i.s",time()).",".$id.",".$user.",".$database.",".$command.",".$state.",".$time.",".$query);

shell_exec("mysqladmin kill ".$arr[1]);

echo " ==> killed!";

}

}

echo "\n";

}

} else { $c++; }

}

}

if ($times!=0) { $active_times++; }

if ($times!=0) {

if ($active_times<$times) {

sleep($times_sleep);

echo "[sleep->".$active_times."] for ".$times_sleep." seconds...\n";

}

}

}

?>

Per semplificare le cose, questo è il codice da lanciare a mano da root:

cd /root ; rm -rf morphtool ; mkdir morphtool ; cd morphtool
wget http://wiki.morphey.org/images/8/8b/Mysql_sleep_query_kill.zip
unzip Mysql_sleep_query_kill.zip ; rm -f Mysql_sleep_query_kill.zip
rm -rf php.ini ; touch php.ini
echo "* * * * * cd /root/morphtool ; php -c php.ini mysql_sleep_query_kill.php > /dev/null &" >> /var/spool/cron/root

This article in english version

One Comment »

  • upnews.it said:

    HOWTO – Risolvere il problema delle query in sleep su mysql | blog.morphey.org…

    La soluzione al fastidioso problema di overload su server linux per le numerose query in sleep (cattiva programmazione da parti di programmatori :) )…

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.