This repository has been archived by the owner on Apr 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
backup.sh
196 lines (166 loc) · 6.56 KB
/
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#!/bin/bash
# Automatic Backup Script by Paddy Xu, 22/07/2014
#
# *) OVERVIEW
#
# This script is designed to perform backup operation of web-files, databases
# and important configuration files on a daily basis. A full backup will be performed
# once a month, while incremental backups is performed on the rest days of the month.
# This script should be run by Cron service, and if necessary, manually.
#
# *) REQUIREMENTS
#
# *) 7-zip full package
# *) Well-configured sendmail service
#
# *) LOGIC
#
# While preforming a full backup, the script will do the following task:
# *) Close BBS
# *) Backup databases
# *) Backup all files
# *) Reopen BBS
# *) Remove full and incremental backup files of last month
#
# If now an incremental backup task is running, the following steps will be performed:
# *) Close BBS
# *) Backup binary log of databases, based on the latest full backup
# *) Do incremental backup for files, based on the latest full backup
# *) Reopen BBS
#
# Noticeably, the incremental backup is always based on the latest full backup, which
# means that an existing incremental backup can be replaced by a latter incremental backup,
# if they are both performed in the same month.
#
# The relation between full and incremental backup can be described as the following graph:
#
# +-------------------------------+-------------------------------+
# | Jan | Feb |
# +-------------------------------+-------------------------------+
# ^ Full 1
# ^------^ Incremental 1.1
# ^--------------^ Incremental 1.2
# ^----------------------^ Incremental 1.3
# +-------------------------------+-------------------------------+
# ^ Full 2
# ^------^ Incremental 2.1
# ^--------------^ Incremental 2.2
# ^----------------------^ Incremental 2.3
# +-------------------------------+-------------------------------+
# ^ Full 3
#
SCRIPT_DIR=$(cd "$(dirname "$0")"; pwd)
ENCRYPT_KEY='GkU0Jx3^l004'
# server configurations
SQL_USER='root'
SQL_PASS='MmW7830@Vb8&'
DATABASE_NAME=("database1" "database2" "database3" "database4")
FILE_DIR_NAME=("git" "web" "nginx" "php" "etc" )
FILE_DIR=( "/home/git" "/home/wwwroot" "/usr/local/nginx/conf" "/usr/local/php/etc" "/etc")
FILE_DIR_LENGTH=${#FILE_DIR_NAME[@]}
CK_LOCK_FILE=/home/wwwroot/example.com/maintain.lock
SQL_LOG_DIR=/usr/local/mariadb/var
BACKUP_DIR=$SCRIPT_DIR/data
FULL_BACKUP_BASE_DIR=$BACKUP_DIR/full
INCR_BACKUP_BASE_DIR=$BACKUP_DIR/incremental
CURRENT_MONTH=$(date +%Y-%m)
CURRENT_DAY=$(date +%Y-%m-%d)
LAST_MONTH=$(date -d last-month +%Y-%m)
YESTERDAY=$(date -d yesterday +%Y-%m-%d)
FULL_BACKUP_DIR=$FULL_BACKUP_BASE_DIR/$CURRENT_MONTH #/home/backup/full/2014-01
INCR_BACKUP_MONTH_DIR=$INCR_BACKUP_BASE_DIR/$CURRENT_MONTH #/home/backup/incremental/2014-01
INCR_BACKUP_DIR=$INCR_BACKUP_BASE_DIR/$CURRENT_MONTH/$CURRENT_DAY #/home/backup/incremental/2014-01/2014-01-03
LAST_FULL_BACKUP_DIR=$FULL_BACKUP_BASE_DIR/$LAST_MONTH #/home/backup/full/2013-12
LAST_INCR_BACKUP_DIR=$INCR_BACKUP_BASE_DIR/$LAST_MONTH #/home/backup/incremental/2013-12
function shutdown_bbs {
echo "Shutting down BBS..."
touch $CK_LOCK_FILE
sleep 5 # wait some time...
}
function reopen_bbs {
echo "Reopening BBS..."
sleep 5 # wait some time...
rm -f $CK_LOCK_FILE
}
function func_full_backup {
echo "Performing full backup..."
#
# Delete existing backup files
#
rm -rf $FULL_BACKUP_DIR/*
rm -rf $INCR_BACKUP_MONTH_DIR/*
rm -rf $LAST_FULL_BACKUP_DIR
rm -rf $LAST_INCR_BACKUP_DIR
#
# Databases
#
echo "Deleting all database binary log files..."
/usr/local/mariadb/bin/mysql -u$SQL_USER -p$SQL_PASS -e 'RESET MASTER'
for db in "${DATABASE_NAME[@]}"
do
echo "Dumping ${db}..."
/usr/local/mariadb/bin/mysqldump -u$SQL_USER -p$SQL_PASS --extended-insert=FALSE ${db} > $FULL_BACKUP_DIR/${db}.sql
done
echo "Rolling up databases..."
7z a -mmt -mhe -mx3 -m0=PPMd -p$ENCRYPT_KEY $FULL_BACKUP_DIR/databases.7z $FULL_BACKUP_DIR/*.sql
rm -f $FULL_BACKUP_DIR/*.sql
echo "Database backup finished"
#
# Files
#
echo "Rolling up files..."
for (( i=0; i<${FILE_DIR_LENGTH}; i++ ))
do
echo "${FILE_DIR_NAME[$i]}: ${FILE_DIR[$i]}:"
7z a -r -mmt -mhe -mx3 -m0=PPMd -p$ENCRYPT_KEY $FULL_BACKUP_DIR/files_${FILE_DIR_NAME[$i]}.7z ${FILE_DIR[$i]}/*
done
echo "Files backup finished"
}
function func_incremental_backup {
echo "Performing incremental backup based on full backup on $CURRENT_MONTH..."
#
# Binary logs
#
echo "Flushing binary log files..."
/usr/local/mariadb/bin/mysql -u$SQL_USER -p$SQL_PASS -e 'FLUSH LOGS'
echo "Copying binary logs..."
temp=(`/usr/local/mariadb/bin/mysql -u$SQL_USER -p$SQL_PASS -B -N -e 'SHOW MASTER STATUS' | xargs`)
current_log=./${temp[0]}
all_logs=(`cat $SQL_LOG_DIR/mysql-bin.index | xargs`)
for log in "${all_logs[@]}"
do
if [ "$log" == "$current_log" ] #Do not copy the log now is using
then
continue
fi
echo "Copying binary log $log"
cp $SQL_LOG_DIR/$log $INCR_BACKUP_DIR/$log
done
echo "Rolling up binary logs..."
7z a -mmt -mhe -mx3 -m0=PPMd -p$ENCRYPT_KEY $INCR_BACKUP_DIR/databases_inc.7z $INCR_BACKUP_DIR/mysql-bin.*
rm -f $INCR_BACKUP_DIR/mysql-bin.*
echo "Database backup finished"
#
# Files
#
echo "Rolling up files incrementally..."
for (( i=0; i<${FILE_DIR_LENGTH}; i++ ))
do
echo "${FILE_DIR_NAME[$i]}: ${FILE_DIR[$i]}:"
7z u $FULL_BACKUP_DIR/files_${FILE_DIR_NAME[$i]}.7z -r -mmt -mhe -mx3 -m0=PPMd -p$ENCRYPT_KEY -u- -up0q3r2x2y2z0w2\!$INCR_BACKUP_DIR/files_${FILE_DIR_NAME[$i]}_inc.7z ${FILE_DIR[$i]}/*
done
echo "Files backup finished"
}
echo "Starting, time is now $(date)"
mkdir -p $FULL_BACKUP_DIR
mkdir -p $INCR_BACKUP_DIR
shutdown_bbs
# If today is the 1st or 15th day of this month, do full backup. Otherwise, do incremental backup.
if [ `date +%d` == 01 ] || [ `date +%d` == 15 ]
then
func_full_backup
else
func_incremental_backup
fi
reopen_bbs
echo "Finished, time is now $(date)"