Though there are a number of database backup tools available in the computer app market, this article is targeted at systems administrators who might not like to get their hands dirty with the complex configuration process involved. For them, we present a simple shell script that will perform the task adequately, with no complications.
This article presents a basic backup shell script that will take a backup of the desired database along with the document root of your website. The script will run via system cron/systemd timers on a pre-defined time and save the backup to a specified directory. Backups will be kept for five days (by default) on the system, after which they will be deleted automatically to save disk space. The script is customisable according to end user needs.
For systems administrators like me, data backups are vital so as to ensure that data is readily available if anything goes wrong. Data can become corrupt due to many reasons, including a disk crash, power failures, an improper shutdown or restart of the server, incorrectly saved data which leads to a hard restart, and the list goes on. In any scenario, if there is a backup available, systems administrators can restore data without getting into the hassle of recovering it from the damaged disk itself.
So here is the simple shell script you could use for backing up your data:
#!/usr/bin/env bash # # Date: 27 January, 2015 # Author: Aman Hanjrah # URI: http://techlinux.net and http://phpnmysql.com # License: GNU GPL v2.0 # Description: The script is used for performing database and document root backup and place it inside a pre-defined directory defined in one of the variables. # # Start function main() { init chkBackupDir } function init() { BACKUP_DIR=/path/to/backup/directory DB_USER=db_user DB_PASSWORD=db_password DB_NAME=db_name DOC_ROOT=/path/to/document/root DAYS_TO_KEEP_BACKUP=5 } function chkBackupDir() { if [[ ! -d $BACKUP_DIR ]]; then mkdir $BACKUP_DIR fi bakupDocRoot } function bakupDocRoot() { `which tar` -cjf $BACKUP_DIR/doc_root_backup-$(date +%d-%m-%y).tar.bz2 --directory=$DOC_ROOT . if [[ -e $BACKUP_DIR/doc_root_backup-$(date +%d-%m-%y).tar.bz2 ]]; then bakupDatabase else echo Backup failed for document root on your server. Please check manually | mail -s Backup failed - Document Root user@domain.com fi } function bakupDatabase() { `which mysqldump` -u $DB_USER -p$DB_PASSWORD $DB_NAME > $BACKUP_DIR/$DB_NAME-$(date +%d-%m-%y).sql | tee $BACKUP_DIR/backup.log tar -cjf $BACKUP_DIR/$DB_NAME-$(date +%d-%m-%y).tar.bz2 $BACKUP_DIR/$DB_NAME-$(date +%d-%m-%y).sql --remove-files 2> $BACKUP_DIR/tar.log if [[ -e $BACKUP_DIR/$DB_NAME-$(date +%d-%m-%y).tar.bz2 ]]; then createTar else echo Backup failed for database on your server. Please check manually | mail -s Backup failed - Database user@domain.com fi } function createTar() { cd $BACKUP_DIR `which tar` -cf backup-$(date +%d-%m-%y).tar doc_root_backup-$(date +%d-%m-%y).tar.bz2 $DB_NAME-$(date +%d-%m-%y).tar.bz2 --remove-files 2> final.log deleteOldBackup } function deleteOldBackup() { `which find` $BACKUP_DIR/$DB_NAME* -mtime +$DAYS_TO_KEEP_BACKUP -exec rm {} \; >> $BACKUP_DIR/delete.log } main # End
Editable options
Given below is the basic information that a user can input in the script.
1. BACKUP_DIR: This is the directory in which backups (database and document root) will be placed.
2. DB_USER: This is the username of the database that you want to take the backup of.
3. DB_PASSWORD: This is the associated password for the username mentioned in the second point.
4. DB_NAME: This is what the database that you want to take a backup of is called.
5. DOC_ROOT: This is the path to the document root where your websites files and directories reside. For example, if your websites content is stored at /usr/share/nginx/html/my_website, then this path has to be defined in the DOC_ROOT variable.
6. DAYS_TO_KEEP_BACKUP: This is self-explanatory. The backup will be kept on the server for the number of days mentioned here. By default, I have set it to five days. Any backup file that is older than that will be removed automatically.
An explanation
This script is modular in nature, which makes it easy to maintain and make changes to add or remove various functionality. Given below is the basic overview:
1. function main() { init chkBackupDir }
A function named main is defined, which contains other functions called init and chkBackupDir. As you will see below, these two functions (defined inside the main function) have different functionalities and the main function just calls them.
2.
function init() { BACKUP_DIR=/path/to/backup/directory DB_USER=db_user DB_PASSWORD=db_password DB_NAME=db_name DOC_ROOT=/path/to/document/root DAYS_TO_KEEP_BACKUP=5 }
The init function is defined, which contains all the variables that need to be initialised when the script runs. Each variable is explained above.
3.
function chkBackupDir() { if [[ ! -d $BACKUP_DIR ]]; then mkdir $BACKUP_DIR fi bakupDocRoot }
The chkBackupDir function is defined, which will check if the backup directory (mentioned by the user in the variable) is present or not. If not, it will be created and the script will move on to the next function, which is bakupDocRoot.
4.
function bakupDocRoot() { `which tar` -cjf $BACKUP_DIR/doc_root_backup-$(date +%d-%m-%y).tar.bz2 --directory=$DOC_ROOT . if [[ -e $BACKUP_DIR/doc_root_backup-$(date +%d-%m-%y).tar.bz2 ]]; then bakupDatabase else echo Backup failed for document root on your server. Please check manually | mail -s Backup failed - Document Root user@domain.com fi }
This function will initiate a backup of the document root of your Web server (defined in one of the variables above) and create a compressed bz2 archive. Then it will check if a bz2 archive exists in the backup directory and only if it does, will it go forward onto the next function, which is backupDatabase. If, for some reason, the archive is not there, or it failed, the script will halt and an email will be dispatched to user@domain.com. You can certainly edit the contents of the email to be sent.
5.
function bakupDatabase() { `which mysqldump` -u $DB_USER -p$DB_PASSWORD $DB_NAME > $BACKUP_DIR/$DB_NAME-$(date +%d-%m-%y).sql | tee $BACKUP_DIR/backup.log tar -cjf $BACKUP_DIR/$DB_NAME-$(date +%d-%m-%y).tar.bz2 $BACKUP_DIR/$DB_NAME-$(date +%d-%m-%y).sql --remove-files 2> $BACKUP_DIR/tar.log if [[ -e $BACKUP_DIR/$DB_NAME-$(date +%d-%m-%y).tar.bz2 ]]; then createTar else echo Backup failed for database on your server. Please check manually | mail -s Backup failed - Database user@domain.com fi }
This function block does two things. First, it takes a backup of the MySQL database in the .sql format, places it inside BACKUP_DIR and creates an archive with bz2 compression. After the archive is created, it will delete the original .sql file. If the bz2 compression is completed, the script will jump to the createTar function and if not, an email will be dispatched to the user.
6.
function createTar() { cd $BACKUP_DIR `which tar` -cf backup-$(date +%d-%m-%y).tar doc_root_backup-$(date +%d-%m-%y).tar.bz2 $DB_NAME-$(date +%d-%m-%y).tar.bz2 --remove-files 2> final.log deleteOldBackup }
This function will simply put two backups (database and document root) in a single .tar file. The archive which is created by this function is not compressed, but merely puts two backups under one file.
7.
function deleteOldBackup() { `which find` $BACKUP_DIR/$DB_NAME* -mtime +$DAYS_TO_KEEP_BACKUP -exec rm {} \; >> $BACKUP_DIR/delete.log }
As the name suggests, this will search for any backup file (.tar) which is $DAYS_TO_KEEP_BACKUP days older and delete it. For example, if the value of $DAYS_TO_KEEP_BACKUP is set to 5, then any backup file which is older than five days will be deleted.
Future possible amendments
This section explains how you can amend this script to get the most out of it and edit it according to your preferences. As you can see, the basic nature of this script is modular, and you may add other functions to it and call them to perform more complex tasks.
For example, if the size of your combined backup (database and document root) is comparatively low, you might want to email it instead of saving it on the server itself.
Another example could be to upload the backup to your Dropbox account. For this purpose, you would need to generate API keys. So Google these!
Yet another example would be to store the backup on an NFS share so that it is placed on another server.
Wrapping up
Numerous backup solutions are available, free or otherwise; so choose one that best meets your requirements, keeping in mind the server overhead that commercial backup tools tend to create. This is where shell scripts come in handy. They achieve the primary backup goal with minimal overhead. As they say, There are multiple ways to do a task in Linux.