Created
August 5, 2016 08:54
-
-
Save borisguery/7b5dd57a43f789b5a35615682213831d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Author: Boris Guéry <[email protected]> | |
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