forked from openemr/openemr-devops
-
Notifications
You must be signed in to change notification settings - Fork 0
/
xrecovery.sh
136 lines (119 loc) · 3.49 KB
/
xrecovery.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
131
132
133
134
135
136
#!/bin/bash
ROOTDIR=/mnt/backups/bkps
WORKDIR=/mnt/backups/recovery
cd $ROOTDIR
USE_MEMORY=1G
CURLOG=$(ls -1 *-info.log | tail -n 1 | sed -e 's/\(.*\)-info.log/\1/')
usage()
{
cat<<EOF >&2
usage: xrecovery.sh [-f <timestamp>] [-m <memory_pool>]
-f <timestamp>: filename batch (without extension) to start recovery from, default latest
-m <memory_pool>: memory to allocate to recovery process, expressed as 250M or 2G, default 1G
EOF
}
while getopts "f:m:" OPTION; do
case $OPTION in
f)
CURLOG=$OPTARG
;;
m)
USE_MEMORY=$OPTARG
;;
?)
usage
exit 1
;;
esac
done
rm -rf $WORKDIR chain-search.txt chain.txt
if [ ! -f $CURLOG.tar.gz ]; then
echo recovery: invalid starting point $CURLOG.tar.gz
exit 1
fi
# do-while
while : ; do
if [ ! -f $CURLOG-info.log ]; then
echo recovery: cannot find target log $CURLOG-info.log
exit 1
fi
if [ ! -f $CURLOG.tar.gz ]; then
echo recovery: cannot find target archive $CURLOG.tar.gz
exit 1
fi
# identify the type of log
CURTYPE=$(grep 'xbackup INFO: Backup type:' $CURLOG-info.log | cut -f 6 -d " ")
if [[ -z "${CURTYPE// }" ]]; then
# not sure I get how this is happening
CURTYPE=full
fi
echo recovery: found $CURLOG, $CURTYPE
echo $CURLOG >> chain-search.txt
# are we done?
[[ $CURTYPE == full ]] && break
echo recovery: following chain...
# parse the current log to find the parent
NEWLOG=$(grep -- --incremental-basedir $CURLOG-info.log | perl -pe 's~.*incremental-basedir /[^[:space:]]*/([^[:space:]]*).*?~\1~')
if [[ $CURLOG == $NEWLOG || "$NEWLOG" == "" ]]; then
echo recovery: could not parse next target, failure
exit 1
else
CURLOG=$NEWLOG
fi
done
# the action chain is backward
tac chain-search.txt > chain.txt
rm chain-search.txt
echo recovery: recovery plan ready!
CURLINE=1
MAXLINE=$(cat chain.txt | wc -l)
while read line; do
rm -rf $line
tar -zxf $line.tar.gz
if [ $MAXLINE -eq 1 ]; then
echo recovery: process single backup $line
xtrabackup --use-memory $USE_MEMORY --prepare --target-dir=$line
if [ $? -ne 0 ]; then
echo recovery: backup preparation failed! not deleting workdir
exit 1
fi
mv $line $WORKDIR
elif [ $CURLINE -eq 1 ]; then
echo recovery: obtain full backup $line
xtrabackup --use-memory $USE_MEMORY --prepare --apply-log-only --target-dir=$line
if [ $? -ne 0 ]; then
echo recovery: initial backup preparation failed! not deleting workdir
exit 1
fi
mv $line $WORKDIR
elif [ $CURLINE -lt $MAXLINE ]; then
echo recovery: apply intermediate incremental $line
xtrabackup --use-memory $USE_MEMORY --prepare --apply-log-only --target-dir=$WORKDIR --incremental-dir=`pwd`/$line
if [ $? -ne 0 ]; then
echo recovery: intermediate recovery failed! not deleting workdir
exit 1
fi
rm -rf $line
else
echo recovery: apply final incremental $line
xtrabackup --use-memory $USE_MEMORY --prepare --target-dir=$WORKDIR --incremental-dir=$line
if [ $? -ne 0 ]; then
echo recovery: final incremental failed! not deleting workdir
exit 1
fi
rm -rf $line
fi
CURLINE=$(($CURLINE+1))
done < chain.txt
rm chain.txt
if ! service mysql status; then
echo recovery: preparations complete, swapping new datadir
/root/xrecovery-final.sh
else
echo recovery: mysql is running, bouncing container
touch /root/pending-restore
service mysql stop
exit 0
fi
echo recovery: complete
exit 0