Such an event is rare, but it does happen. It happened to me not that long ago. Fortunately, I had made a backup about a week prior to the server crash. I also used Google's caching feature to capture the content of the missing week. I believe I only lost one post and about one week's worth of comments (translation: roughly 3 comments). Not too bad, but it inspired me to do better. I found a backup script and modified it to meet my own needs. Now, a complete backup of my MovableType database is e-mailed to me each evening.
In case there might be some other folks also interested in having a 'safety-net', this post contains both the script and installation instructions.
Please note that this script backs up a MySQL database. If you are using MT but not MySQL, this will not help you. Also note that if you use any other blogging software that does use MySQL, then this script will also work for you. Finally, your server must have both php support and cron for this to work.
Here are step by step instructions on creating an automated backup:
Step 1: Create a File Containing the Script
<?php // mySQL backup & mail v1.02 // created by: Justin O. Kirk // // copyrighted © 2001-2002 Justin Kirk // Enhancements added by: King of Fools // // http://www.king-of-fools.com // October, 2003 // { Added compression option } // { Added datestamp option } // Run Script As: // php -q /home/yourusername/locationofscript/backup_db.php // // * Must be run using ssh or cron // * Browser execution will fail // * Take appropriate security precautions // (Your DB Password is in this file) //*** BEGIN variables ***// // Backup Time Variables $backupdate = date("F j, Y"); $backuptime = date("H:i"); //*** Edit Below ***// // ========================== // MySQL DATABASE INFORMATION // ========================== // database host: (blank if localhost) $dbhost = ''; // name of the database: $database = 'dbname'; // username with db access: $username = 'dbuser'; // password for username: $password = 'dbpassword'; // ============================== // BACKUP FILENAME & LOCATION // ============================== // filename for the backup: (no extension) $backupas = "mysql"; // absolute path to backup destination: (no trailing slash) $backupto = '/home/username/tmp'; // =================== // E-MAIL INFORMATION: // =================== // who the mail is from. $mailname = 'autobackup'; // reply address (not needed) $mailfrom = ''; // email address to send the database to. $mailto = 'you@yourdomain.com'; // subject of email. $subject = "MySQL Backup - $backupdate"; // message body. $message = "Backup Created at $backuptime on $backdate:"; // ======== // OPTIONS: // ======== $send_email = '1'; // 1=send backup copy via e-mail. 0= backup data, don't e-mail. $delete_local = '1'; // 1=delete local copy when done. 0=leave local copy when done. $compress_archive = '1'; // 1=compress archive file with gzip. 0=I like large emails. $date_stamp = '1'; // 1=add datestamp to archive file. 0=Always use same backup name //*** END of variables. ***// //*************************************// //*** Do Not Edit Beyond This Point ***// //*************************************// // Resolve Archive Target: if ($date_stamp) { $backupas = $backupas.'_'.date("Ymd"); } $backupfile = $backupas.'.sql'; // Call Functions backupdb(); if ($compress_archive) { compressdb(); } if ($send_email) { makeandsend(); } if ($delete_local) { removedb(); } // Functions function backupdb() { global $dbhost,$username,$password,$database,$backupto,$backupfile; if($dbhost == "") { $backupcommand = "mysqldump -u$username -p$password $database >$backupto/$backupfile"; } else { $backupcommand = "mysqldump -h$dbhost -u$username -p$password $database >$backupto/$backupfile"; } passthru ("$backupcommand", $error); if($error) { echo ("Dump Problem: $errorn"); exit;} } function compressdb() { global $backupto,$backupfile; $compresscmd = "cd $backupto; gzip -f $backupfile"; passthru ("$compresscmd", $error); if($error) { echo ("GZip Problem: $errorn"); exit; } $backupfile = $backupfile.'.gz'; } function removedb() { global $backupto,$backupfile; if(!unlink("$backupto/$backupfile")) { echo ("Cannot Remove $backupto/$backupas"); exit;} } function makeandsend() { global $backupto,$backupfile,$message,$mailto,$subject,$mailname,$mailfrom,$database; $mail_boundary = '--=nextpart_' . md5(uniqid(time())); $mail_head = "From: $mailnamernReply-to: $mailfromrn"; $mail_head .= "MIME-Version: 1.0rn"; $mail_head .= "Content-type: multipart/mixed; boundary="$mail_boundary""; $mail_head .= "rnrn"; $mail_head .= "This is a multi-part message in MIME format."; $mail_head .= "rnrn"; $db_file = $backupto.'/'.$backupfile; $fp = fopen($db_file, "r"); $file = fread($fp, filesize($db_file)); $file = chunk_split(base64_encode($file)); $mail_body = "--$mail_boundaryrn"; $mail_body .= "Content-type: text/plain; charset=us-asciirn"; $mail_body .= "Content-transfer-encoding: 8bitrnrn"; $mail_body .= " $messagern"; $mail_body .= "--$mail_boundaryrn"; $filename = basename($db_file); $mail_body .= "Content-type: application/octet-stream; name="$filename"rn"; $mail_body .= "Content-transfer-encoding:base64rn"; $mail_body .= "Content-Disposition: attachment; filename="$filename"rnrn"; $mail_body .= $file. "rnrn"; $mail_body .= "--$mail_boundary--"; mail($mailto, $subject, $mail_body, $mail_head); } ?>
Step 2: Modify the Script Variables
- $dbhost Specifies the database host. It can be left blank if the database is hosted on your own domain. This value should be in the DBHost line in your mt.cfg. If there is no DBHost line, then it should be left blank.
- $database Specifies the database name. This value is
required and should be in the Database line in your mt.cfg. - $username Specifies the user with access to the database. This value is
required and should be in the DBUser line in your mt.cfg. - $password Specifies the password for the username. This value is
required and should be in your mt-db-pass.cgi. - $backupto Specifies the location where the backup should be created. This value is
required . Running mt-check.cgi should give you a clue as to what the path structure of your site is. I would suggest placing the database in a directory called tmp just of the public_html. - $mailto Specifies the location where the backup should be sent. This value is
required if $sendemail is set to '1'. It should contain the e-mail address you want the backup e-mailed to. - $send_email Determines if the backup should be e-mailed or not. '1'=send e-mail, '0'=do not send.
- $delete_local Determines if the local copy should be deleted after it is e-mailed. '1'=delete local copy; '0'=leave local copy. This option is a good way to save space, but if you are not e-mailing the backup anywhere, then you do not want to delete the local copy.
- $compress_archive Determines if the backup should compressed or not. '1'=compress backup; '0'=no compression. If your server does not have gzip installed, this must be set to '0'.
- $date_stamp Determines if the backup filename should have a date-stamp in it. '1'=use date in filename; '0'=standard backup name.
Step 3: Load the Script onto Your Server
Step 4: Create a Cron Job for the Backup
30 23 * * * php -q /home/userdir/scripts/backup_db.php > /dev/null
Other Notes
I had to make a shell script which called the backup script. Here it is:
PATH=/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/local/msql/bin export PATH cd /homepages/99/d99999999/htdocs/cron echo "Executing Backup Script..." echo "==========================n" php4 -q backup_db.php echo "n==========================n" echo "Backup Script Complete!"
50 23 * * * sh /homepages/99/d99999999/htdocs/cron/backup.sh > /dev/null
If you want automatic backups but this looks impossible to pull off by yourself, I would be willing to set it up for you (for a small fee). Contact me via e-mail if you are interested.



