Skip to content

Instantly share code, notes, and snippets.

@gfarrell
Created October 22, 2012 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gfarrell/3932741 to your computer and use it in GitHub Desktop.
Save gfarrell/3932741 to your computer and use it in GitHub Desktop.
Backs up database and files to given remote server via scp
#!/bin/bash
##########################################################
# Remote Backup Script
#
# FILE: remote_backup.sh
# RUN: Daily 00h00
#
# author: Gideon Farrell me@gideonfarrell.co.uk
##########################################################
set -e
# Switches
backup_files=false
backup_database=true
backup_cron=true
log_severity=1
keep_for_days=7
# File variables
server="my.server.local:/path/to/backups"
mntdir="/mnt/backup";
tmpdir="/tmp/backup";
logdir="/var/log/backup/";
# Database variables
db[0]='backup'
db[1]='mypassword'
# Backup things
backupdirs=("/var/www/mysite1" "/var/www/mysite2")
databases=("my_site_db_one" "my_site_db_two")
####
#
# Lasciate ogne speranza, voi ch'intrate (don't edit past here pls, Dante says)
#
####
# Setup new vars
log="$logdir/`date +%Y%m%d`.log";
bkpdir="$mntdir/`date +%Y%m%d`";
sumf="$tmpdir/checksums.txt";
stamp="/$mntdir/backup.stamp";
cdir=`pwd`
# Functions
function log {
if [ $2 -le $log_severity ]; then
echo -e "$1";
echo -e "$1" >> "$log";
fi
}
function logbr {
echo -e "";
echo -e "" >> "$log";
}
# Deal with log dir
if [ ! -d "$logdir" ]; then
mkdir -p "$logdir";
fi
# If a log exists already for today, append a number to it
if [ -e "$log" ]; then
index=1;
tmplog="$log.$index"
while [ -e "$tmplog" ]; do
((index++))
tmplog="$log.$index";
done
mv "$log" "$tmplog";
fi
touch "$log"
### Begin ###
log "Starting backup: `date`" 0
# Clear tmp directories
logbr
log "Clearing tmp dir at $tmpdir" 1
if [ -d "$tmpdir" ]; then
log "- $tmpdir exists, removing" 2
rm -rf "$tmpdir";
fi
# Create tmp dir
logbr
log "Creating tmp dir at $tmpdir" 0
mkdir -p "$tmpdir"
# Backup files if necessary
if $backup_files; then
logbr
log "Backup files flag set to true, beginning file backup." 0
length=${#backupdirs[*]}
log "$length directories to back up: ${backupdirs[@]}" 1
index=0
while [ $index -lt $length ]; do
dir="`basename ${backupdirs[$index]}`";
out="$tmpdir/f_$dir.tar.gz"
log "Backing up ${backupdirs[$index]}" 1
if [ ! -d "${backupdirs[$index]}" ]; then
log "- Directory doesn't exist!" 0
((index++))
continue;
fi
tar -czf "$out" "${backupdirs[$index]}"
((index++))
done
fi
# Backup databases if necessary
if $backup_database; then
logbr
log "Backup databases flag set to true, beginning DB backup." 0
length=${#databases[*]}
log "$length databases to backup: ${databases[*]}" 1
index=0
while [ $index -lt $length ]; do
db_name=${databases[$index]}
out_sql="$tmpdir/d_$db_name.sql"
out="$tmpdir/d_$db_name.tar.gz"
log "Backing up $db_name" 1
touch "$out_sql";
mysqldump \
-u ${db[0]} \
-p"${db[1]}" \
--add-drop-database \
--add-drop-table \
--comments \
$db_name >> "$out_sql"
log "Compressing SQL output" 2
tar -czf "$out" "$out_sql";
rm -f "$out_sql";
((index++))
done
fi
# Backup crontab if necessary
if $backup_cron; then
logbr
log "Backup cron flag set to true, beginning cron backup." 0
out="$tmpdir/crontab";
crontab -l > "$out"
fi
# Create a file list
files=`ls "$tmpdir"`;
# Generate checksums
logbr
log "Creating checksums." 0
checklist=""
for f in $files; do
if [ "$f" != "backup.log" ]; then
checklist="$checklist $f";
fi
done
log "Moving into $tmpdir" 1
cd "$tmpdir"
log "Now in `pwd`" 1
md5sum $checklist >> "$sumf";
log "`cat "$sumf"`" 1
logbr
log "Moving back to $cdir" 1
cd "$cdir"
log "Now in `pwd`" 1
# Refresh file list
files=`ls "$tmpdir"`;
# Mount the server if not mounted
logbr
log "Mounting server" 0
if mount | grep "${server} on ${mntdir} type" > /dev/null; then
log "Server already mounted" 1
else
mount "$server" "$mntdir"
fi
# Create directory
# If the directory already exists, make space
logbr
log "Creating backup directory" 0
if [ -e "$bkpdir" ]; then
log "Backup directory already exists, making space" 1
index=1;
bkpdir_tmp="$bkpdir.$index"
while [ -e "$bkpdir_tmp" ]; do
((index++))
bkpdir_tmp="$bkpdir.$index";
done
mv "$bkpdir" "$bkpdir_tmp";
log "Moved backup directory to $bkpdir_tmp, continuing to backup to $bkpdir" 1
fi
mkdir -p "$bkpdir";
# Copy contents of tmp dir in to backup dir
logbr
log "Copying backup" 0
for f in $files; do
log "Copying $f" 1
cp -f "$tmpdir/$f" "$bkpdir/$f";
done;
# Check copying worked
# Clean tmpdir if everything copies nicely
logbr
log "Verifying..." 0
log "Moving into $bkpdir" 1;
cd "$bkpdir";
log "Now in `pwd`" 1;
md5sum -c "$bkpdir/checksums.txt" --status
logbr
if [ $? -eq 0 ]; then
log "Checksums are valid." 0
log "Copy completed successfully. Cleaning out tmp dir $tmpdir" 0
rm -rf "$tmpdir";
else
log "Checksums are invalid." 0
log "Copy failed, leaving tmp dir intact $tmpdir" 0
fi
logbr
log "Moving back to $cdir" 1
cd "$cdir"
log "Now in `pwd`" 1
# Copy logfile over
logbr
log "Copying log file and finishing up." 0
cp "$log" "$bkpdir/backup.log";
# Remove old backups
logbr
log "Removing old backups." 0
find "$mntdir" -type d -atime +${keep_for_days} -regex "^\/mnt\/backup\/[0-9]+" -exec rm -r {} \;
# Remove old logs
logbr
log "Removing old logs." 0
find "$logdir" -type d -atime +${keep_for_days} -exec rm -r {} \;
# Unmount drive
logbr
log "Unmounting backup drive" 0
umount -l "$mntdir";
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment