Setting Up Automated MySQL Database Backups on HTTPme Servers
 

I needed a way to backup individual MySQL databases and was using a nice little scheme that called "mutt" in a CRON to send the output results to me. Unfortunately mutt is no longer a standard install on the servers and they would prefer we use Exim. How to do that? I was stumped and finally figured out that the standard *nix "sendmail" was aliased to Exim. The theory here would be that if the mail server is changed to something other than Exim, this would still work.

This database backup is configured per domain as I didn't need them all backed up every day, but needed some of them twice a day so this can be run as often as wanted with a CRON job. After the job runs, the compressed sql dump file will be emailed to the address indicated in the script (explained below in detail).

IMPORTANT:
Transfer ALL files in ASCII mode (not the FTP default mode).

There will be a zipped file at the end that you can download - it contains the sample shell script, the sample php mailer script and a PDF document of these instructions in landscape format. You'll need to get the mailer class from the link also furnished at the bottom.

 

webdomain.com (account username: webdom) will be used as an example:

  1. Using FTP, create a directory called /backup on the domain's account, above the web root:
    /home/webdom/backup (this directory is at the same level as "public_html")

  2. Create a directory named "logs" in the backup directory
    /home/webdom/backup/logs

    Add an empty text file under /logs called Errorlog.txt -- if you let the script add the file, it may not be accessible. Create a text file in your favorite editor, put one word in it (I wrote 'beginning') and save it as Errorlog.txt; move it to /home/webdom/backup/logs - it may not allow you to move an empty file.

  3. Set permissions on both of these directories to "755" and the file "Errorlog.txt" to 644.

  4. FTP the file "class.phpmailer.php" to the backup directory. (See end of article for source)
    Permissions can be left at "644" (-rw-r--r--)
    This class file supports the mail program. No changes need to be made to this file in order to use it for another domain.

  5. The file that does the actual mailing and needs changes is called "mysqlbackup.php" and will be placed in the /backup directory with permissions of "755". Changes needed to this file are outlined below. All the red comments can be removed. Create a text file called mysqlbackup.php (or use the sample in the download) and only put in the black lines, with your changes.

  6. #!/usr/bin/php
    <?php
    // include the mailer class

    /* change the 'webdom' in the next line to reflect the account username of the appropriate domain */
    require_once('/home/webdom/backup/class.phpmailer.php');

    // create an instance of the mailer
    $mail = new PHPMailer();
    // use sendmail for the mailer - it's aliased to Exim mail on the server
    $mail->IsSendmail();

    /* the From address must be a valid address - you can use the accountname @ domain.com as shown below */
    $mail->From = "webdom@webdomain.com";

    /* this is the "name" before the email address and can be blank " " or whatever you select */
    $mail->FromName = "DbBackup";


    /* next is the receiving person's address. If you want more than one person to receive the mail, make another line exactly like the one below and change the receiver's address:
    $mail->AddAddress("user1@some_ISP.com");
    $mail->AddAddress("user2@some_ISP.net");
    */

    $mail->AddAddress("your_email@your_ISP.com");


    $mail->WordWrap = 50;


    /* a CRON job explained later will create the mysql backup file. Insert the name of that file here - it Must be the same name as the file being created in the CRON. Each time the CRON is processed it will overwrite this file on the server so we don't have files accumulating. The second part (after the comma) gives the file a unique name ("mysqlbu_webdomDB_28JAN04.sql.gz") so when you receive the attachment you won't have to rename it in order to keep several files on your local machine. Be sure to change the "webdom" in the path to the appropriate user account and change the file name */
    $mail->AddAttachment("/home/webdom/backup/mysqlbu_webdomDB.sql.gz", "mysqlbu_webdomDB_".date("dMy").".sql.gz");
    /* NO CARRIAGE RETURN - above is ALL ONE LINE */

    /* this is obviously the message subject and can be whatever you want */

    $mail->Subject = "WebDom DB Backup";

    /* same here - anything you want to put in the body of the message */
    $mail->Body = "This is a backup of the WebDom MySQL database";

    /* next - a little error handling. If there is a script error while trying to send the mail, the error should be written to the directory shown. Be sure to change "webdom" to the appropriate account username. Make sure you have added an empty text file called "Errorlog.txt" in the /home/webdom/backup/logs directory. If the script creates it, it will be unusable.*/
    if(!$mail->Send())
    {
    $fp = fopen("/home/webdom/backup/logs/Errorlog.txt", "a");
    fwrite($fp, "Message could not be send. <p>" . "Mailer Error: " . $mail->ErrorInfo);
    fclose($fp);
    exit;
    }
    ?>


    Move this file to the server and change permissions as noted in the first sentence of step 5.

    If for some reason the mail gets created but is undeliverable, check the /home/webdom/mail directory (at the same level as your public_html directory) and download the "inbox" file to view it. Returned mail will end up here.

  7. Now create a text file called "mysqlbackup.sh". This file will also go in the directory /home/webdom/backup and permissions need to be "755".


    Note the changes in red:
    a. First red item is the database userID
    b. Second red item is the database password (the reason we're keeping all this out of the web root)
    c. Third red item is the database name
    d. Fourth red item is the account username in the path
    e. Fifth red item can be whatever identifies this sql backup file for you - remember it ALSO has to be exactly the same in the "AddAttachment" statement in step 5 above.
    f. Sixth red item - name of the path where your Errorlog.txt file resides.

    g. Seventh red item calls the mail script so change the path to the right account username.


    mysqldump -uwebdom_dbuserid -pdbpswd webdom_dbname --all --add-drop-table -Q | gzip > "/home/webdom/backup/mysqlbu_webdomDB.sql.gz" 2>>"/home/webdom/backup/logs/Errorlog.txt"
    php -q /home/webdom/backup/mysqlbackup.php


    The first line, "mysqldump" statement, creates the zipped backup in sql format.
    The second line, the call to "php", calls the mailer script created above.
    Only two lines in this file, watch the wrap or use the sample in the download.
    Move this file to the server as described in the first sentence above in step 6. [REMEMBER ASCII MODE FOR FTP]

  8. Now, setup a CRON job to run this thing.
    - Go to CPANEL for the appropriate account
    - Click on "Cron Jobs" under the Advanced menu
    - I use the "Advanced (Unix Style) window to setup my job.
    - Enter your email address for output - in case the CRON fails, you'll be notified.
    - In the command box, enter: /home/webdom/backup/mysqlbackup.sh
      (change the account username to the appropriate value)
    - The Hour field is in GMT so since I'm 6 hours "off" from GMT in Minnesota, I would enter 15 (3 p.m. military) to run it at 9 a.m.

    I won't go into the values for the rest of the fields - here's a pretty good tutorial that explains the other values:
    http://www.webmasters-central.com/t/cron.shtml

  9. That's it - test it by setting the CRON to something a few minutes in the future and then wait for the mail to come. Don't Forget to go back and set the CRON values for your real, desired schedule.

  10. The SQL file you receive will have "--" for the comment lines - these need to be changed to "##" in order to use the file to restore your database. If anyone knows how to fix this, please pipe up!

Credits:
The PHPMailer class came from: http://phpmailer.sourceforge.net -- download to get more examples, more explanation of the settings available, and of course, the 'class.phpmailer.php' file.

The original idea came from a post here: http://www.HTTPme.com/showthread.php?threadid=8897 - I simply replaced the method of sending the email. Thanks to all who contributed to the above thread.

Download Sample Files (10k)

I apologize for being so verbose but was trying to remember the days when I didn't have a clue how to do any of these things! This works on Comet and Cheetah - should be pretty generic.