Bash backup rotation script

A while ago I was looking for a good backup script, and there were none. It had to be fast, to cope with big data sizes, and configurable so I could set how many days to keep backups.

This folder structure has to be created manually. Rotation script will take anything in incomming folder and move it to appropriate destination backup archive.

drwxr-xr-x 15 root root 4096 Apr 23 06:44 backup.daily
drwxr-xr-x  4 root root 4096 Apr  1 06:29 backup.monthly
-rwxr-x---  1 root root 1386 Feb 21 11:53 backup.sh
drwxr-xr-x 10 root root 4096 Apr 20 06:38 backup.weekly
drwxr-xr-x  2 root root 4096 Apr 23 06:44 incoming

Here is the my original script translated to English:

backup.sh

#!/bin/bash
# Julius Zaromskis
# Backup rotation

# Storage folder where to move backup files
# Must contain backup.monthly backup.weekly backup.daily folders
storage=/home/backups/your_website_name

# Source folder where files are backed
source=$storage/incoming

# Destination file names
date_daily=`date +"%d-%m-%Y"`
#date_weekly=`date +"%V sav. %m-%Y"`
#date_monthly=`date +"%m-%Y"`

# Get current month and week day number
month_day=`date +"%d"`
week_day=`date +"%u"`

# Optional check if source files exist. Email if failed.
if [ ! -f $source/archive.tgz ]; then
ls -l $source/ | mail your@email.com -s "[backup script] Daily backup failed! Please check for missing files."
fi

# It is logical to run this script daily. We take files from source folder and move them to
# appropriate destination folder

# On first month day do
if [ "$month_day" -eq 1 ] ; then
  destination=backup.monthly/$date_daily
else
  # On saturdays do
  if [ "$week_day" -eq 6 ] ; then
    destination=backup.weekly/$date_daily
  else
    # On any regular day do
    destination=backup.daily/$date_daily
  fi
fi

# Move the files
mkdir $destination
mv -v $source/* $destination

# daily - keep for 14 days
find $storage/backup.daily/ -maxdepth 1 -mtime +14 -type d -exec rm -rv {} \;

# weekly - keep for 60 days
find $storage/backup.weekly/ -maxdepth 1 -mtime +60 -type d -exec rm -rv {} \;

# monthly - keep for 300 days
find $storage/backup.monthly/ -maxdepth 1 -mtime +300 -type d -exec rm -rv {} \;

Please note – only file rotation is performed, it is up to you to copy your backup to source folder (incoming). For faster operations, files are moved from the source folder! Here is what I use on one of the servers, to backup entire website:

/etc/cron.daily/my_website_backup

#!/bin/bash
#@author Julius Zaromskis
#@description Backup script for your website

BACKUP_DIR=/home/backups/your_website_name
FILES_DIR=/var/www/your_website_name

# Dump MySQL tables
mysqldump -h 127.0.0.1 -u admin -pyourpassword database > $BACKUP_DIR/incoming/mysql_dump.sql

# Compress tables and files
tar -cvzf $BACKUP_DIR/incoming/archive.tgz $BACKUP_DIR/incoming/mysql_dump.sql $FILES_DIR

# Cleanup
rm $BACKUP_DIR/incoming/mysql_dump.sql

# Run backup rotate
cd $BACKUP_DIR
bash backup.sh
Advertisements

9 thoughts on “Bash backup rotation script

  1. Recent mail clients are more fussy. Need to put email address at end of line, i.e change:-

    ls -l $source/ | mail your@email.com -s “[backup script] Daily backup failed! Please check for missing files.”

    to

    ls -l $source/ | mail -s “[backup script] Daily backup failed! Please check for missing files.” your@email.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s