Skip to content

Instantly share code, notes, and snippets.

@borisguery
Created August 5, 2016 08:54
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 borisguery/7b5dd57a43f789b5a35615682213831d to your computer and use it in GitHub Desktop.
Save borisguery/7b5dd57a43f789b5a35615682213831d to your computer and use it in GitHub Desktop.
#!/bin/bash
# Author: Boris Guéry <guery.b@gmail.com>
usage() {
cat <<EOF
usage: $0 <command> [-h] [-y] [-vvv] [-d] [<args>]
Currently supported commands are:
push Push current database data to S3
pull Download latest database snapshot and remove existing one
EOF
}
return_with_error() {
echo "fatal:" $@ >&2
exit 1
}
run() {
if [[ "$VERBOSE" -ge 2 ]]; then
echo "->" $@
fi
if [[ "$DRY_RUN" -eq 0 ]]; then
if [[ "$VERBOSE" -ge 2 ]]; then
$@
else
$@ > /dev/null 2>&1
fi
if [[ "$?" -ne 0 ]]; then
if [[ "$VERBOSE" -lt 2 ]]; then
return_with_error "an error occured, run with -vv to debug"
else
exit 1
fi
fi
fi
}
log() {
if [[ "${VERBOSE}" -ge 1 ]]; then
echo "->" $@
fi
}
parse_options() {
while getopts "hvdy" OPTION
do
case ${OPTION} in
h)
usage
exit 1
;;
v)
VERBOSE=$((VERBOSE+1))
;;
d)
DRY_RUN=1
;;
y)
ASSUME_YES=1
;;
esac
done
}
print_version() {
local version="${VERSION}"
if [[ ${REVISION} != '$rev$' ]]; then
version="${version}r${REVISION}"
fi
echo "version: ${version}"
}
confirm() {
if [[ ${ASSUME_YES} -eq 0 ]]; then
read -r -p "-? $1" response
case ${response} in
$2)
true
;;
*)
false
;;
esac
else
true
fi
}
exit_if_not_root() {
[ "$UID" -ne 0 ] && return_with_error "you must be root"
}
VERBOSE=0
DRY_RUN=0
ASSUME_YES=0
VERSION="0.1"
REVISION='$rev$'
DATABASE_REVISION="latest"
DATABASE_SNAPSHOT_S3_URI="s3://productreview-au-dev/mysql-backup/database-dev-${DATABASE_REVISION}.tar.gz"
DATABASE_SERVER_USER="root"
DATABASE_SERVER_PASSWORD=""
push() {
local temp_dir=$(mktemp -d)
log Created temp directory: ${temp_dir}
log Creating backup
local innobackupex_output=$(innobackupex --user=${DATABASE_SERVER_USER} --password=${DATABASE_SERVER_PASSWORD} --compress --compress-threads=4 --no-timestamp ${temp_dir} 2>&1)
if [[ $? -ne 0 || ${innobackupex_output} != *"completed OK!"* ]]; then
if [[ ${VERBOSE} -le 1 ]]; then
return_with_error "innobackupex errored, run with -vv to debug"
else
return_with_error "innobackupex errored: ${innobackupex_output}"
fi
fi
run cd ${temp_dir}
temp_archive_name=$(mktemp)
run tar -cz . -f ${temp_archive_name}
log Archive created ${temp_archive_name}
log Pushing archive to S3
run aws s3 cp ${temp_archive_name} ${DATABASE_SNAPSHOT_S3_URI}
log Cleaning temp files and directories
run rm -fr ${temp_dir}
run rm -f ${temp_archive_name}
}
pull() {
local temp_dir=$(mktemp -d)
log Created temp directory: ${temp_dir}
local temp_downloaded_archive_name=$(mktemp)
log Downloading archive...
run aws s3 cp ${DATABASE_SNAPSHOT_S3_URI} ${temp_downloaded_archive_name}
log Extracting archive...
run tar -C ${temp_dir} -xzf ${temp_downloaded_archive_name}
run cd ${temp_dir}
log Decompressing backup
run innobackupex --decompress .
log Preparing backup
run innobackupex --apply-log .
log Stopping MySQL services
run service mysql stop
confirm "Are you TOTALLY sure, it will delete all the existing databases? [y/N] " "[yY]" || { echo "Bye chicken."; exit 0; }
local existing_datadir_backup_dir=$(mktemp -d)
run mkdir -p /var/lib/mysql/
run mv /var/lib/mysql/* ${existing_datadir_backup_dir}
log I created a backup of the existing datadir in ${existing_datadir_backup_dir}
run find /var/lib/mysql/ -mindepth 1 -delete
run innobackupex --copy-back ${temp_dir}
run chown -R mysql: /var/lib/mysql
log Restarting MySQL services
run service mysql start
confirm "If everything ran properly, you may want to remove existing backup, do you? [y/N] " "[yY]" && { run rm -fr ${existing_datadir_backup_dir}; }
run rm -fr ${temp_dir}
run rm -f ${temp_downloaded_archive_name}
}
case $1 in
push)
exit_if_not_root
shift
parse_options $@
shift $((OPTIND-1)); OPTIND=1
push $@
exit 0
;;
pull)
exit_if_not_root
shift
parse_options $@
shift $((OPTIND-1)); OPTIND=1
pull $@
exit 0
;;
usage)
usage
exit 0
;;
--version)
print_version
exit 0
;;
*)
usage
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment