jeudi, février 27, 2014

Why CrashPlan Kicks Ass

CrashPlan is righteously presenting itself as
"The most comprehensive backup solution".
Commenting on Mauricio Prinzlau's article, How Crashplan Online Backup Service Trumps Competition, I felt I needed to give some complementary indications on why Code 42's CrashPlan software is such an efficient and flexible backup solution. In the end, I felt the comment itself would make a great blog post! So here it is.

One thing that is pretty cool with CrashPlan is that you can backup your files accross your different local or remote computers, and you are even allowed to share backup storage space with friends. It actually allows you to do that with the free version.

To save some bandwidth, you can backup large data sets on a local drive, copy it on a portable drive and import it on any other computer with CrashPlan running (yours or your friends'), and CrashPlan will automatically identify the backup and start syncing it right away across the network.

It's also easier when you need to restore a lot of data: just copy and import the backup set back to the original computer, and you won't need to rely on the network or CrashPlan to send you a hard drive to restore your data [yes, they can].

As the data is compressed and encrypted, the owner remains the only person to have access to the actual backed-up data, so privacy-wise it is bullet-proof, too. Just keep your password strong, and to yourself.

Using a combination of paid licensing (where you need to split a lot of data in multiple "backup sets") and free licensing for computers with simpler needs, you can manage your own off-site backup cloud for the entire office, as well as all your family members and your friends, while keeping the overall backup budget to the lowest and maximizing your storage and bandwidth cost.

CrashPlan is very good software, however there are a few issues that can show up once in a while. In particular, one should be aware that when backuping data located on a removable drive, make sure the drive remains connected to the computer. If it remains disconnected for a few days and CrashPlan keeps running, it might silently sweep off the backed-up data from the backup destinations (local, off-site and CrashPlan cloud as well). It happened to me once after a source hard drive had a fault, and it remained offline for a certain time while I was running an interminable chkdsk on it, using another computer. Since some files where corrupted after the fault and CrashPlan swept away the backups -- exactly at the moment I would have needed them -- CrashPlan ended up being useless. But if I knew this beforehand, I would immediately have made a copy of the backup set and saved the day. So you better know this.

It can also become a headache when, for some obscure reason, one computer is suddenly unable to reach any backup destination, even though they are online. CrashPlan do it's best to establish the connections without needing to reconfigure your firewalls and routers, but you can encounter situations that require you to read through the manuals and forums to fix them.

But overall, I agree that CrashPlan is, as far as I know, the most innovative, complete, painless and affordable backup solution on the market nowadays.

vendredi, février 14, 2014

Déménager une immense base de données avec phpMyAdmin

Le transfert du contenu d'une base de données d'un serveur à l'autre (ou même d'une base à l'autre) avec phpMyAdmin est une opération assez simple : il suffit généralement d'exporter le contenu de la base source sous forme d'une requête SQL pour ensuite l'importer dans la nouvelle base.

Mais les choses peuvent se corser lorsque le fichier de requête SQL produit pèse plusieurs centaines de mégaoctets. Effectivement, le serveur de destination risque de ne pas arriver à traiter d'un coup une requête de cette taille. D'autant plus qu'en tentant de télécharger en amont un tel fichier, même compressé, vous risquez d'atteindre le délai limite d'exécution du serveur avant d'avoir réussi à le télécharger.

C'est ce qui m'est arrivé récemment en essayant de déménager une base de données Piwik sur un nouveau serveur, le fichier SQL produit pesant quelques 537 Mo !

J'ai donc développé la solution suivante pour fragmenter un immense fichier SQL en plusieurs petites requêtes qui pourront être importées une à une. J'ai ensuite modifié le script pour qu'il produise des fichiers gzippés, question de minimiser la bande passante (et surtout le temps de téléchargement) au moment de l'importation.

Dans ce cas-ci, mon fichier SQL s'appelait "piwik.sql". Le script "sql-split-gz.php", placé dans le même répertoire, contient le code PHP suivant :

<?php
$source = 'piwik';
$part_threshold = 40*1024*1024;
if(!$f = fopen($source.'.sql','r')) die("No such file: $source.sql");
mkdir("$source.part");

$part = 1;
$size = 0;
#$o = fopen($fn="$source.part/$part.sql",'w+');
$o = gzopen($fn="$source.part/$part.sql.gz",'w9');

while($line = fgets($f,4096)) {
 if(substr($line,0,7)==='INSERT ') {
  if($size >= $part_threshold) {
   #fclose($o);
   gzclose($o);
   echo "$fn ($size)\r\n";
   $part++;
   $size = 0;
   #$o = fopen($fn="$source.part/$part.sql",'w+');
   $o = gzopen($fn="$source.part/$part.sql.gz",'w9');
  }
 }
 #fwrite($o,$line);
 gzwrite($o,$line);
 $size += strlen($line);
}
#fclose($o);
gzclose($o);
echo "$fn ($size)\r\n";
fclose($f);
?>

Le script créera un dossier nommé "piwik.part" et y placera les fichier SQL numérotés, avec l'extension .sql.gz. Il suffira ensuite d'importer ces fichiers un par un dans phpMyAdmin, qui interprète nativement les fichiers gzippés. Mais attention ! Il faudra les importer dans le même ordre !

Fonctionnement

Le script lit le fichier SQL source ligne par ligne. Il écrit chaque ligne dans le fichier de sortie actuel, en commençant par "1.sql.gz". Lorsqu'il rencontre une requête "INSERT", il vérifie si la quantité de données (non-compressées) déjà écrites dans le fichier de sortie dépasse la valeur de $part_treshold (ici configurée à 40 Mo, soit 40 * 1024 * 1024 octets). Le cas échéant, la variable $part est incrémentée et les données sont écrites dans le fichier de sortie suivant.

Il faut donc modifier la variable $source pour qu'elle corresponde au nom de votre fichier source (sans l'extension ".sql") et la variable $part_treshold à la taille désirée. Une valeur plus élevée donnera des fragments moins nombreux mais plus volumineux. Cependant, gardez à l'idée que phpMySQL peut imposer une limite de taille aux fichiers importés (dans mon cas elle est de 50 Mo sur mon serveur de destination).

Attention : la valeur $part_treshold n'est pas une limite de taille, mais, comme son nom l'indique, un seuil : étant testée seulement à chaque requête "INSERT", la quantité de données (non compressées) écrites dans chaque fichier de sortie dépasse nécessairement cette grandeur. Dans ce cas-ci, puisque les fichiers de sortie sont gzippés, on pourrait néanmoins se permettre une valeur plus grande (dans mon cas, le plus gros fichier de sortie produit ne pèse que 17,8 Mo), ce que j'aurais peut-être dû faire, tout compte fait, pour réduire le nombre d'importations successives nécessaires.