-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbtrfs-backup.sh
executable file
·130 lines (104 loc) · 2.31 KB
/
btrfs-backup.sh
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/bin/bash
#
# Implementation
#
# out: $SNAPSHOT
snapshot() {
local DB TIMESTAMP s
DB=api_production
# first lock MySQL
mysql -u root -popensuse $DB -e "FLUSH TABLES WITH READ LOCK;"
if [ $? -ne 0 ]; then
echo "Failed to lock Database, aborting!"
return 2
fi
# create snapshot
TIMESTAMP=`date +%Y-%m-%d-%H:%M`
btrfs subvolume snapshot -r "${SOURCE}." "${SOURCE}${SNAPSHOTS}${TIMESTAMP}"
if [ $? -ne 0 ]; then
echo "Failed to create snapshot!"
s=3
fi
# unlock MySQL
mysql -u root -popensuse $DB -e "UNLOCK TABLES;"
if [ $? -ne 0 ]; then
echo "Failed to unlock Database!"
s=1
fi
# force btrfs flush
sync
SNAPSHOT="${TIMESTAMP}"
return $s
}
# out: $TRANSFERCMD
transfercmd() {
local MODE OLD NEW
if [ $# -eq 2 ]; then
# initial transfer
NEW="$2"
printf -v SENDCMD 'btrfs send "%s"' "${SOURCE}${SNAPSHOTS}${NEW}"
printf -v RECVCMD 'btrfs receive "%s"' "${DESTINATION}${SNAPSHOTS}"
elif [ $# -eq 3 ]; then
# differential transfer
OLD="$2"
NEW="$3"
printf -v SENDCMD 'btrfs send -p "%s" "%s"' "${SOURCE}${SNAPSHOTS}${OLD}" "${SOURCE}${SNAPSHOTS}${NEW}"
printf -v RECVCMD 'btrfs receive "%s"' "${DESTINATION}${SNAPSHOTS}"
else
echo "Usage: $0 <push|pull> [<old snapshot>] <new snapshot>"
exit 1
fi
MODE=$1
case $MODE in
pull)
printf -v TRANSFERCMD "ssh %s '%s' | pv | %s" "${SSHOPTIONS}" "${SENDCMD}" "${RECVCMD}"
return 0
;;
push)
printf -v TRANSFERCMD "%s | pv | ssh %s '%s'" "${SENDCMD}" "${SSHOPTIONS}" "${RECVCMD}"
return 0
;;
*)
echo "Invalid mode specified, aborting!"
return 1
;;
esac
}
# out: $OLD, $NEW
getlatestsnapshots() {
OLD=
NEW=
LIST=`ls "${SOURCE}${SNAPSHOTS}" | sort | tail -2`
for token in $LIST; do
OLD="$NEW"
NEW="$token"
done
}
#
# Configuration
#
# location of source volume
SOURCE=/srv/obs/
# location of snapshots relative to source (destination) volume
SNAPSHOTS=snapshots/
# location of destination volume
DESTINATION=/media/obs-data/
# ssh cmdline options (e.g. hostname, port, password, ...)
SSHOPTIONS="-p 3022 [email protected]"
# mode of operation (pull/push)
MODE=pull
#
# Execution
#
# first create a snapshot
snapshot
if [ $? -ne 0 ]; then
# too bad
exit 1
fi
# find snapshots
getlatestsnapshots
# generate transfer command
transfercmd $MODE $OLD $NEW
echo "Use this command to transmit:"
echo $TRANSFERCMD