Skip to content

Instantly share code, notes, and snippets.

@mrl22
Last active June 9, 2023 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mrl22/f64b8ea3e8cf4f30db7d382a13d1eeeb to your computer and use it in GitHub Desktop.
Save mrl22/f64b8ea3e8cf4f30db7d382a13d1eeeb to your computer and use it in GitHub Desktop.
Server Backup - Files and MySQL to SSH Server using Rsync with Hardlink support to save space

Server Backup

Files and MySQL to SSH Server using Rsync with Hardlink support to save space.

Improved 06/10/2022

This script will keep six daily, three weekly and three monthly rsync hardlinked backup of /etc, /home, /var/www and /root. It will also create a gzipped MySQL dump of the whole server inside each backup.

You must have already have public key access to the remote user.

Hardlink support will reduce usage space dramatically. More information on hardlinks

Run the following:

bash -c "$(wget -qO - 'gist.githubusercontent.com/mrl22/f64b8ea3e8cf4f30db7d382a13d1eeeb/raw/backup.sh')" '' -b remoteserver.com -u backupuser

or set it up in a cronjob:

0 2 * * * bash -c "$(wget -qO - 'gist.githubusercontent.com/mrl22/f64b8ea3e8cf4f30db7d382a13d1eeeb/raw/backup.sh')" '' -b remoteserver.com -u backupuser

Make sure to change the options:

-b = The host or IP of the remote SSH/Rsync Server. -u = The user name on the remote server.

Useful commands

List available backups on the backup server

for dir in $(ls|egrep -i '^backup\.(daily|weekly|monthly)'); do echo -n "$dir : "; cat "$dir/backup.txt"; done;

Have you found this useful? Buy me a coffee.

#!/usr/bin/env bash
usage() { echo "Usage: $0 [-b <backup_server>] [-u <remote_user>]" 1>&2; exit 1; }
while getopts ":b:u:" o; do
case "${o}" in
b)
backup_server=${OPTARG}
;;
u)
backup_user=${OPTARG}
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
if [ -z "${backup_user}" ] || [ -z "${backup_server}" ]; then
usage
fi
day_of_week=`date +%u`
day_of_month=`date +%d`
backup_start=`date +%s`
# I have had to disable multiple backups for now due to huge space usage
ssh $backup_user@$backup_server "rm -rf backup.daily5; rm -rf backup.daily4; rm -rf backup.daily3; rm -rf backup.daily2;"
ssh $backup_user@$backup_server "rm -rf backup.weekly3; rm -rf backup.weekly2;"
ssh $backup_user@$backup_server "rm -rf backup.monthly3; rm -rf backup.monthly2;"
# Daily
#ssh $backup_user@$backup_server "\
#[ -d 'backup.daily5' ] && rsync -aH --delete backup.daily5/* backup.daily6; \
#[ -d 'backup.daily4' ] && rsync -aH --delete backup.daily4/* backup.daily5; \
#[ -d 'backup.daily3' ] && rsync -aH --delete backup.daily3/* backup.daily4; \
#[ -d 'backup.daily2' ] && rsync -aH --delete backup.daily2/* backup.daily3; \
#[ -d 'backup.daily1' ] && rsync -aH --delete backup.daily1/* backup.daily2; \
#"
rsync -a --delete /etc /home /var/www /root $backup_user@$backup_server:backup.daily1
# MySQL Backup
mysqldump --single-transaction --skip-lock-tables --all-databases | gzip -c | ssh $backup_user@$backup_server "cat > backup.daily1/mysql-backup.sql.gz"
if [ $day_of_week -eq 1 ]
then
# Weekly
#ssh $backup_user@$backup_server "\
#[ -d 'backup.weekly2' ] && rsync -aH --delete backup.weekly2/* backup.weekly3; \
#[ -d 'backup.weekly1' ] && rsync -aH --delete backup.weekly1/* backup.weekly2; \
#"
ssh $backup_user@$backup_server "rsync -aH --delete backup.daily1/* backup.weekly1"
fi
if [ $day_of_month -eq 01 ]
then
# Monthly
#ssh $backup_user@$backup_server "\
#[ -d 'backup.monthly2' ] && rsync -aH --delete backup.monthly2/* backup.monthly3; \
#[ -d 'backup.monthly1' ] && rsync -aH --delete backup.monthly1/* backup.monthly2; \
#"
ssh $backup_user@$backup_server "rsync -aH --delete backup.daily1/* backup.monthly1"
ssh $backup_user@$backup_server "rm -rf mysql" # Remove at a later date
fi
backup_end=`date +%s`
backup_runtime=$((backup_end-backup_start))
backup_hours=$((backup_runtime / 3600)); backup_minutes=$(( (backup_runtime % 3600) / 60 )); backup_seconds=$(( (backup_runtime % 3600) % 60 ));
mysql_date=`date +\%Y-\%m-\%d-\%H.\%M.\%S`
ssh $backup_user@$backup_server "echo -e '$mysql_date ($backup_hours:$backup_minutes:$backup_seconds)' >> backup-log.txt; echo -e '$mysql_date ($backup_hours:$backup_minutes:$backup_seconds)' > backup.daily1/backup.txt"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment