Thursday 11 March 2010

Linux backup

For a little while now, I've been backup in my server to a removable hard disc. This has worked pretty well till a couple of months ago when I inserted the backup drive into the server (the drive is in a caddy). This caused the computer to switch off! and their was a nasty burning smell. I feared that I'd fried the computer, but it turned out to be the hard disc.

So rather than replace the hard disc, I started to think about a better solution. The problem with removable hard discs is that you can't automate regular backups. This lead me to start thinking about NAS drives. A network storage device could sit on the network and be used to backup to on a regular basis. I have a central server in my house witch all the other desktops, media center's and laptops backup to. So this means only the server needs to be backed up. Because it's Linux I needed a NAS that supported things like rsync and NFS. It's also important that files copied from the server to retain their permissions and owner ship.

After speaking to friends and looking around the Internet I deiced on the Netgear ReadyNAS duo. This can take two hard discs, and has loads of features, including NFS and rsync. The device works well in Linux, Windows or OSX. The documentation does not really mention Linux.

Once connected network I powered it on and got a scare. The device was very loud. Turns out this is a not problem, as it settled down. In fact I've never heard it do that again. Its actually very quite. Next I followed the setup wizard you get when you access the admin interface for the first time. I then added a backup NFS share. The share was configured to be accessible only from the server and allow root to mount it.

Now I use the following script to perform backups. It's still a working in progress (let me know if you have suggestions for improvement). This performs a incremental backup to the mounted NFS share.
#! /usr/bin/perl

use File::Path;
use File::Copy;
use File::Temp;

my $BACKUP_DIR="/mounts/backup";
my $RSYNC_OPTIONS="-a --delete -v";
my $NUM_BACKUPS=4;
my @DIRS=("/usr/local/","/etc/","/srv/","/home/","/root/","/var/lib/samba/","/mnt/Films/Films/");

my $backupPrefix=$BACKUP_DIR."/backup.";

for ($count=$NUM_BACKUPS; $count>=1 ; $count--) {
if ($count==$NUM_BACKUPS) {
if ( -d $backupPrefix.$count ) {
print "Delete backup ".$backupPrefix.$count;
rmtree($backupPrefix.$count);
}
}
else {
my $previousDir=$backupPrefix.($count-1);
if ( -d $previousDir ) {
print "Moving backup ".$previousDir." to ".$backupPrefix.$count."\n";
move($previousDir,$backupPrefix.$count);
}
}
}

if ( -d $backupPrefix."1" ) {
print "Copying previous backup\n";
system("cp -al ".$backupPrefix."1/. ".$backupPrefix."0");
}

print "Backup up latest system changes\n";
foreach $dir (@DIRS) {
print "Backup up changes in ".$dir."\n";
mkpath($backupPrefix."0".$dir);
system("rsync ".$RSYNC_OPTIONS." ".$dir." ".$backupPrefix."0".$dir);
}

my $backupDataPath=$backupPrefix."0/backup-data";
if ( -d $backupDataPath ) {
rmtree($backupDataPath);
}

mkpath($backupDataPath);
system("rpm -qa > ".$backupDataPath."/packages.list");

No comments: