Ero un felice utente di MySQLDumper fino a quando Tophost non ha aggiornato i server all’architettura cloud e all’ultima versione di PHP, cosa che ha comportato la scomparsa di un paio di moduli PERL necessari e mi ha lasciato a terra (la routine PHP di MySQLDumper è molto lenta ed usa javascript per ricaricare le pagine, il che la rende incompatibile sia con wget che cronjob remoti come SetCronJob.com).
Così ho cercato e trovato due guide su internet (questa, e questa), le ho mischiate assieme potenziando soprattutto il codice di David Walsh, ho aggiunto un pizzico di compressione bzip2, e ho messo il tutto sul mio spazio web.
Ho rimosso la parte in cui è possibile selezionare quali tabelle salvare: ho pensato che un backup degno di questo nome è “all-inclusive”, e in fondo chiunque avesse il bisogno particolare di salvare solo alcune tabelle dovrebbe essere anche piuttosto navigato da poter modificare il codice in proprio.
AGGIORNAMENTO 9/9/11: siccome ne avevo bisogno (lo script andava incontro ad un errore di memoria insufficiente) ho aggiunto qualche riga per riattivare la lista delle tabelle da ignorare, basta riempire l’array con i nomi che vi servono.
Questo è il risultato:
<?php $creationstart=strtok(microtime()," ")+strtok(" "); $dbhost="indirizzo.server.mysql"; $dbname="nomedatabase"; $dbuser="usernamemysql"; $dbpass="passwordmysql"; $mailto="scrivimi@lamiacasella.it"; $subject="Backup DB"; $from_name="Il tuo caro sito web"; $from_mail="noreply@ilmiosito.it"; mysql_connect($dbhost, $dbuser, $dbpass); mysql_select_db($dbname); $tablesblocklist=array( "tablename1"=>1, "tablename2"=>1, "tablename3"=>1, ); $tables = array(); $result = mysql_query("SHOW TABLES"); while($row = mysql_fetch_row($result)) $tables[] = $row[0]; foreach($tables as $table) { if (!isset($tablesblocklist[$table])) { $result = mysql_query("SELECT * FROM $table"); $return.= "DROP TABLE IF EXISTS $table;"; $row2 = mysql_fetch_row(mysql_query("SHOW CREATE TABLE $table")); $return.= "\n\n".$row2[1].";\n\n"; while($row = mysql_fetch_row($result)) { $return.= "INSERT INTO $table VALUES("; $fields=array(); foreach ($row as $field) $fields[]="'".mysql_real_escape_string($field)."'"; $return.= implode(",",$fields).");\n"; } $return.="\n\n\n"; } } $filename='db-backup-'.date("Y-m-d H.m.i").'.sql.bz2'; $content=chunk_split(base64_encode(bzcompress($return,9))); $uid=md5(uniqid(time())); $header= "From: ".$from_name." <".$from_mail.">\r\n". "Reply-To: ".$replyto."\r\n". "MIME-Version: 1.0\r\n". "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n". "This is a multi-part message in MIME format.\r\n". "--".$uid."\r\n". "Content-type:text/plain; charset=iso-8859-1\r\n". "Content-Transfer-Encoding: 7bit\r\n\r\n". $message."\r\n\r\n". "--".$uid."\r\n". "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n". "Content-Transfer-Encoding: base64\r\n". "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n". $content."\r\n\r\n". "--".$uid."--"; mail($mailto,$subject,"",$header); $creationend=strtok(microtime()," ")+strtok(" "); $creationtime=number_format($creationend-$creationstart,4); echo "Backup del database completato, compresso a bz2 e spedito per posta elettronica in $creationtime secondi"; ?>
(WordPress ha rimosso l’indent e non ho voglia di aggiustarlo a mano)
L’intera routine viene completata in circa 7secondi sul mio non tanto sveglio server Tophost, inclusi la compressione bzip2 e l’invio per posta elettronica, mentre il salvataggio del file in formato solo testo nel codice originale di David impiegava sullo stesso server 17secondi; probabilmente la differenza è dovuta alla rimozione di diversi cicli ridondanti, e all’uso delle funzioni native mysql_real_escape_string() e implode().
Sinceri ringraziamenti vanno ai rispettivi autori delle guide, senza le quali non stare scrivendo questa paginetta oggi 😉