-
Notifications
You must be signed in to change notification settings - Fork 0
/
backup_mysql_to_s3
executable file
·93 lines (84 loc) · 2.63 KB
/
backup_mysql_to_s3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/bin/bash
# packs up mysql databases and directories and push them up to S3
# -- init --
umask 077
whisper(){ [[ -t 0 ]] && echo "$*"; } # be quiet in cronjobs
die(){ echo >&2 "$1"; exit "${2:-1}"; }
# is mysql even here?
if ! systemctl is-active --quiet mysql; then
whisper "mysqld is not running; aborting"
exit 0;
fi
# config defaults
AWS_OPTS=("--cli-connect-timeout=10")
# load config
cd "$(dirname "$(readlink -f -- "$0")")" || exit 1;
for f in "$HOME/.config/s3-backup.cfg" "$HOME/.s3-backup.cfg" "./s3-backup.cfg"; do
# shellcheck disable=SC1090
[ -e "$f" ] && source "$f" && break;
done
if [[ -z "$S3BUCKET" ]]; then
echo >&2 "no cfg file found"; exit 1;
fi
# verify we have the programs we need
_verify_needs(){
local awsver retval
retval=0
if [[ -z "$S3BUCKET" ]]; then
echo >&2 "EROR S3BUCKET not set"
retval=1
fi
for i in aws gzip head mysql mysqldump sort; do
if ! command -v "$i" >/dev/null; then
echo >&2 "EROR need program: ${i}"
retval=1
fi
done
[[ $retval == 0 ]] || return $retval
awsver=$(aws --version) # aws-cli/2.9.3 Python/3.9.11 Linux/5.15.91-1
awsver=${awsver%% *} ; awsver=${awsver#*/} ;
if [[ "$( echo -e "$awsver\n1.10" |sort -rV |head -1 )" != "$awsver" ]]; then
echo >&2 "EROR need aws --version >=1.10; saw $awsver"
retval=1
fi
return $retval
}
# which subdir are we uploading these to?
# AWS S3 expiry policies use the first umpteen characters of an
# object's name i.e. "anything named s3://bucket/backups_daily/* expire
# after 8 days"
_build_s3_prefix() {
local path today wday mday
path=""
today=$(printf '%(%F)T')
wday=$(( $(printf '%(%u)T') % 7 ))
mday=$(printf '%(%d)T')
if [[ "${wday#0}" -eq 0 ]] && [[ "${mday#0}" -lt 8 ]]; then
path="backups_monthly/$today"
elif [[ "$wday" == "0" ]]; then
path="backups_weekly/$today"
else
path="backups_daily/$today"
fi
[[ -n "$S3PREFIX" ]] && path="$S3PREFIX/$path"
echo "$path"
}
# -- main() --
_verify_needs || die "pre-flight check failed"
objprefix="s3://${S3BUCKET}/$(_build_s3_prefix)"
AWS_OPTS+=("--output=text" "--color=off")
[[ -t 0 ]] || AWS_OPTS+=("--quiet")
UPLOADCMD=("aws" "${AWS_OPTS[@]}" "s3" "cp")
if [[ -z "${MYSQL_DATABASES[*]}" ]]; then
mapfile -t MYSQL_DATABASES < <(mysql -BN -e 'show databases;' \
|grep -vE '^(information_schema|mysql|performance_schema|sys)$')
fi
for dbname in "${MYSQL_DATABASES[@]}"; do
whisper "Sending $dbname to $objprefix/$dbname.sql.gz"
if [[ -n "$DRYRUN" ]]; then
echo "mysqldump --skip-comments \"$dbname\" |gzip -ncf - |${UPLOADCMD[*]} - \"$objprefix/$dbname.sql.gz\""
else
mysqldump --skip-comments "$dbname" |gzip -ncf - \
|"${UPLOADCMD[@]}" - "$objprefix/$dbname.sql.gz"
fi
done