Skip to content

Commit 89e3100

Browse files
committed
Added skip option
1 parent 8923a11 commit 89e3100

File tree

3 files changed

+157
-99
lines changed

3 files changed

+157
-99
lines changed

.env-example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ SKIP_DATABASES=mysql,sys,information_schema,performance_schema,phpmyadmin
1212

1313
# (Optional) Command called on script success, WITH the double quotes !
1414
# ON_SUCCESS="echo 'Hello world'"
15+
16+
# Skip some steps ( structure, data, routines, triggers, events, views, users, grants )
17+
# Example to skip everything
18+
# SKIP_OP=structure,data,routines,triggers,events,views,users,grants

README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![codecov](https://codecov.io/gh/williamdes/sql-backup/branch/master/graph/badge.svg)](https://codecov.io/gh/williamdes/sql-backup)
55
[![License: Unlicense](https://img.shields.io/badge/license-Unlicense-blue.svg)](http://unlicense.org/)
66

7-
Backup your MySQL / MariaDB server ( data, users, grants, views, triggers, routines, events )
7+
Backup your MySQL / MariaDB server ( structure, data, users, grants, views, triggers, routines, events )
88

99
## Install
1010

@@ -20,12 +20,14 @@ cp .env-example .env
2020
```bash
2121
nano .env
2222
```
23-
or
23+
or
24+
2425
```bash
2526
vi .env
2627

2728
```
28-
then
29+
then
30+
2931
```
3032
./backup.sh
3133
```
@@ -39,11 +41,12 @@ export BACKUP_CONFIG_ENVFILE="/home/myuser/secretbackupconfig.env.txt"
3941
./backup.sh
4042

4143
unset BACKUP_CONFIG_ENVFILE
42-
```
43-
You can use the variables of the env file in the `ON_SUCCESS` variable, example :
44+
```
45+
You can use the variables of the env file in the `ON_SUCCESS` variable, example :
46+
4447
```bash
4548
ON_SUCCESS="${BACKUP_DIR}/onsuccessscript.sh"
46-
```
49+
```
4750

4851

4952
## Options
@@ -57,6 +60,7 @@ ON_SUCCESS="${BACKUP_DIR}/onsuccessscript.sh"
5760
| SKIP_DATABASES | | YES |
5861
| EXPERT_ARGS | --default-character-set=utf8 --extended-insert=FALSE --single-transaction --skip-comments --skip-dump-date --hex-blob --tz-utc | YES |
5962
| ON_SUCCESS | | YES |
63+
| SKIP_OP | | YES |
6064

6165
> ON_SUCCESS is called on script success
6266
@@ -68,6 +72,7 @@ MYSQL_HOST=localhost
6872
MYSQL_USER=root
6973
MYSQL_PASS=root
7074
SKIP_DATABASES=mysql,sys,information_schema,performance_schema,phpmyadmin
75+
SKIP_OP=users,grants
7176
```
7277

7378
## Files

backup.sh

Lines changed: 142 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ exitWithMsg() {
55
exit $1
66
}
77

8+
hasSkip() {
9+
for e in "${SKIP_OP[@]}"; do
10+
if [ "$e" == "$1" ]; then
11+
return 1
12+
fi
13+
done
14+
return 0
15+
}
16+
817
# from : github:builtinnya/dotenv-shell-loader
918
DOTENV_SHELL_LOADER_SAVED_OPTS=$(set +o)
1019
set -o allexport
@@ -45,6 +54,18 @@ if [ -z "${MYSQL_USER}" ]; then
4554
exitWithMsg 200 "Empty Variable MYSQL_USER"
4655
fi
4756

57+
if [ -z "${SKIP_OP}" ]; then
58+
SKIP_OP=()
59+
else
60+
SKIP_OPS=$(echo -e "${SKIP_OP}" | tr "," "\n")
61+
SKIP_OP=()
62+
oldIFS=$IFS
63+
IFS=$'\n'
64+
for SKIP in $SKIP_OPS; do
65+
SKIP_OP+=(${SKIP} )
66+
done
67+
IFS=$oldIFS
68+
fi
4869

4970
MYSQL_CONN="-h${MYSQL_HOST} -u${MYSQL_USER}"
5071

@@ -87,128 +108,156 @@ for DB in $DB_LIST; do # Concat ignore command
87108
DBS="${DBS} ${DB}"
88109
done
89110

90-
VIEW_LIST_SQL="SET SESSION group_concat_max_len = 1000000;SELECT IFNULL(GROUP_CONCAT(concat(':!\`',table_schema,'\`.\`',table_name,'\`') SEPARATOR ''),'') FROM information_schema.views"
111+
hasSkip "views"
112+
if [ "$?" -eq 0 ]; then
113+
VIEW_LIST_SQL="SET SESSION group_concat_max_len = 1000000;SELECT IFNULL(GROUP_CONCAT(concat(':!\`',table_schema,'\`.\`',table_name,'\`') SEPARATOR ''),'') FROM information_schema.views"
114+
115+
# If ${SKIP_DATABASES} is not empty, create a where chain
116+
if [ ! -z "${SKIP_DATABASES}" ]; then
117+
VIEW_LIST_SQL="${VIEW_LIST_SQL} WHERE table_schema NOT IN ("
118+
# Split on ,
119+
SKIP_DATABASES=$(echo -e "${SKIP_DATABASES}" | tr "," "\n")
120+
for DB in ${SKIP_DATABASES} ; do
121+
VIEW_LIST_SQL="${VIEW_LIST_SQL}'${DB}'," ;
122+
done
123+
VIEW_LIST_SQL="${VIEW_LIST_SQL: : -1}"
124+
VIEW_LIST_SQL="${VIEW_LIST_SQL});"
125+
else
126+
VIEW_LIST_SQL=";"
127+
fi
91128

92-
# If ${SKIP_DATABASES} is not empty, create a where chain
93-
if [ ! -z "${SKIP_DATABASES}" ]; then
94-
VIEW_LIST_SQL="${VIEW_LIST_SQL} WHERE table_schema NOT IN ("
95-
# Split on ,
96-
SKIP_DATABASES=$(echo -e "${SKIP_DATABASES}" | tr "," "\n")
97-
for DB in ${SKIP_DATABASES} ; do
98-
VIEW_LIST_SQL="${VIEW_LIST_SQL}'${DB}'," ;
99-
done
100-
VIEW_LIST_SQL="${VIEW_LIST_SQL: : -1}"
101-
VIEW_LIST_SQL="${VIEW_LIST_SQL});"
102-
else
103-
VIEW_LIST_SQL=";"
104-
fi
129+
# Get result
130+
VIEWS_LIST=$(mysql ${MYSQL_CONN} -ANe"${VIEW_LIST_SQL}")
105131

106-
# Get result
107-
VIEWS_LIST=$(mysql ${MYSQL_CONN} -ANe"${VIEW_LIST_SQL}")
132+
if [ "$?" -ne 0 ]; then
133+
exitWithMsg 205 "Views listing failed"
134+
fi
108135

109-
if [ "$?" -ne 0 ]; then
110-
exitWithMsg 205 "Views listing failed"
136+
VIEW_IGNORE_ARG=()
137+
# Split on :!
138+
VIEWS=$(echo -e "${VIEWS_LIST}" | tr ":!" "\n")
139+
# echo -e "${VIEWS}"
140+
141+
oldIFS=$IFS
142+
IFS=$'\n'
143+
for VIEW in $VIEWS; do # Concat ignore command
144+
# Replace ` in ${VIEW}, does not work with ` for --ignore-table
145+
VIEW="${VIEW//\`/}"
146+
#VIEW=$(printf '%q' "${VIEW}")
147+
VIEW_IGNORE_ARG+=(--ignore-table=${VIEW} )
148+
done
149+
IFS=$oldIFS
150+
# echo "${VIEW_IGNORE_ARG[@]}";
111151
fi
112152

113-
VIEW_IGNORE_ARG=()
114-
# Split on :!
115-
VIEWS=$(echo -e "${VIEWS_LIST}" | tr ":!" "\n")
116-
# echo -e "${VIEWS}"
117-
118-
oldIFS=$IFS
119-
IFS=$'\n'
120-
for VIEW in $VIEWS; do # Concat ignore command
121-
# Replace ` in ${VIEW}, does not work with ` for --ignore-table
122-
VIEW="${VIEW//\`/}"
123-
#VIEW=$(printf '%q' "${VIEW}")
124-
VIEW_IGNORE_ARG+=(--ignore-table=${VIEW} )
125-
done
126-
IFS=$oldIFS
127-
# echo "${VIEW_IGNORE_ARG[@]}";
128-
echo "Structure..."
129-
mysqldump ${MYSQLDUMP_DEFAULTS} --skip-add-drop-table --routines=FALSE --triggers=FALSE --events=FALSE --no-data "${VIEW_IGNORE_ARG[@]}" --databases ${DBS} > ${BACKUP_DIR}/structure.sql
153+
hasSkip "structure"
154+
if [ "$?" -eq 0 ]; then
155+
echo "Structure..."
156+
mysqldump ${MYSQLDUMP_DEFAULTS} --skip-add-drop-table --routines=FALSE --triggers=FALSE --events=FALSE --no-data "${VIEW_IGNORE_ARG[@]}" --databases ${DBS} > ${BACKUP_DIR}/structure.sql
130157

131-
if [ "$?" -ne 0 ]; then
132-
exitWithMsg 207 "Structure dump failed"
158+
if [ "$?" -ne 0 ]; then
159+
exitWithMsg 207 "Structure dump failed"
160+
fi
133161
fi
134162

135-
echo "Data ..."
136-
mysqldump ${MYSQLDUMP_DEFAULTS} --routines=FALSE --triggers=FALSE --events=FALSE --no-create-info "${VIEW_IGNORE_ARG[@]}" --databases ${DBS} > ${BACKUP_DIR}/database.sql
163+
hasSkip "data"
164+
if [ "$?" -eq 0 ]; then
165+
echo "Data ..."
166+
mysqldump ${MYSQLDUMP_DEFAULTS} --routines=FALSE --triggers=FALSE --events=FALSE --no-create-info "${VIEW_IGNORE_ARG[@]}" --databases ${DBS} > ${BACKUP_DIR}/database.sql
137167

138-
if [ "$?" -ne 0 ]; then
139-
exitWithMsg 208 "Data dump failed"
168+
if [ "$?" -ne 0 ]; then
169+
exitWithMsg 208 "Data dump failed"
170+
fi
140171
fi
141172

142-
echo "Routines ..."
143-
mysqldump ${MYSQLDUMP_DEFAULTS} --routines=TRUE --triggers=FALSE --events=FALSE --no-create-info --no-data --no-create-db --databases ${DBS} > ${BACKUP_DIR}/routines.sql
173+
hasSkip "routines"
174+
if [ "$?" -eq 0 ]; then
175+
echo "Routines ..."
176+
mysqldump ${MYSQLDUMP_DEFAULTS} --routines=TRUE --triggers=FALSE --events=FALSE --no-create-info --no-data --no-create-db --databases ${DBS} > ${BACKUP_DIR}/routines.sql
144177

145-
if [ "$?" -ne 0 ]; then
146-
exitWithMsg 209 "Routines dump failed"
178+
if [ "$?" -ne 0 ]; then
179+
exitWithMsg 209 "Routines dump failed"
180+
fi
147181
fi
148182

149-
echo "Triggers ..."
150-
mysqldump ${MYSQLDUMP_DEFAULTS} --routines=FALSE --triggers=TRUE --events=FALSE --no-create-info --no-data --no-create-db --databases ${DBS} > ${BACKUP_DIR}/triggers.sql
183+
hasSkip "triggers"
184+
if [ "$?" -eq 0 ]; then
185+
echo "Triggers ..."
186+
mysqldump ${MYSQLDUMP_DEFAULTS} --routines=FALSE --triggers=TRUE --events=FALSE --no-create-info --no-data --no-create-db --databases ${DBS} > ${BACKUP_DIR}/triggers.sql
151187

152-
if [ "$?" -ne 0 ]; then
153-
exitWithMsg 210 "Triggers dump failed"
188+
if [ "$?" -ne 0 ]; then
189+
exitWithMsg 210 "Triggers dump failed"
190+
fi
154191
fi
155192

156-
echo "Events ..."
157-
mysqldump ${MYSQLDUMP_DEFAULTS} --routines=FALSE --triggers=FALSE --events=TRUE --no-create-info --no-data --no-create-db --databases ${DBS} > ${BACKUP_DIR}/events.sql
193+
hasSkip "events"
194+
if [ "$?" -eq 0 ]; then
195+
echo "Events ..."
196+
mysqldump ${MYSQLDUMP_DEFAULTS} --routines=FALSE --triggers=FALSE --events=TRUE --no-create-info --no-data --no-create-db --databases ${DBS} > ${BACKUP_DIR}/events.sql
158197

159-
if [ "$?" -ne 0 ]; then
160-
exitWithMsg 211 "Events dump failed"
198+
if [ "$?" -ne 0 ]; then
199+
exitWithMsg 211 "Events dump failed"
200+
fi
161201
fi
162202

163-
echo "Views ..."
164-
VIEWS_SHOW_SQL=""
165-
oldIFS=$IFS
166-
IFS=$'\n'
167-
for VIEW in $VIEWS; do # Concat SHOW CREATE VIEW command
168-
VIEWS_SHOW_SQL="${VIEWS_SHOW_SQL}SHOW CREATE VIEW ${VIEW};"
169-
done
170-
IFS=$oldIFS
171-
172-
# echo -e "${VIEWS_SHOW_SQL}"
173-
echo ${VIEWS_SHOW_SQL} | sed 's/;/\\G/g' | mysql ${MYSQL_CONN} > ${BACKUP_DIR}/views.sql
203+
hasSkip "views"
204+
if [ "$?" -eq 0 ]; then
205+
echo "Views ..."
206+
VIEWS_SHOW_SQL=""
207+
oldIFS=$IFS
208+
IFS=$'\n'
209+
for VIEW in $VIEWS; do # Concat SHOW CREATE VIEW command
210+
VIEWS_SHOW_SQL="${VIEWS_SHOW_SQL}SHOW CREATE VIEW ${VIEW};"
211+
done
212+
IFS=$oldIFS
213+
214+
# echo -e "${VIEWS_SHOW_SQL}"
215+
echo ${VIEWS_SHOW_SQL} | sed 's/;/\\G/g' | mysql ${MYSQL_CONN} > ${BACKUP_DIR}/views.sql
216+
217+
if [ "$?" -ne 0 ]; then
218+
exitWithMsg 212 "Views dump failed"
219+
fi
174220

175-
if [ "$?" -ne 0 ]; then
176-
exitWithMsg 212 "Views dump failed"
221+
#Keeps lines starting with Create
222+
sed -i '/Create/!d' ${BACKUP_DIR}/views.sql
223+
# Removes 'Create View'
224+
sed -i -e 's/Create\ View://g' ${BACKUP_DIR}/views.sql
225+
#add ; at lines end
226+
sed -i 's/)$/);/' ${BACKUP_DIR}/views.sql
227+
#Remove spaces before start of line
228+
sed -i 's/^ *//' ${BACKUP_DIR}/views.sql
229+
#Add ; at line end
230+
sed -i 's/$/;/' ${BACKUP_DIR}/views.sql
231+
#Replace double ;; by ;
232+
sed -i 's/;;/;/' ${BACKUP_DIR}/views.sql
177233
fi
178234

179-
#Keeps lines starting with Create
180-
sed -i '/Create/!d' ${BACKUP_DIR}/views.sql
181-
# Removes 'Create View'
182-
sed -i -e 's/Create\ View://g' ${BACKUP_DIR}/views.sql
183-
#add ; at lines end
184-
sed -i 's/)$/);/' ${BACKUP_DIR}/views.sql
185-
#Remove spaces before start of line
186-
sed -i 's/^ *//' ${BACKUP_DIR}/views.sql
187-
#Add ; at line end
188-
sed -i 's/$/;/' ${BACKUP_DIR}/views.sql
189-
#Replace double ;; by ;
190-
sed -i 's/;;/;/' ${BACKUP_DIR}/views.sql
191-
192-
echo "Users ..."
193-
mysqldump ${MYSQLDUMP_DEFAULTS} mysql --no-create-info --complete-insert --tables user db > ${BACKUP_DIR}/users.sql
235+
hasSkip "users"
236+
if [ "$?" -eq 0 ]; then
237+
echo "Users ..."
238+
mysqldump ${MYSQLDUMP_DEFAULTS} mysql --no-create-info --complete-insert --tables user db > ${BACKUP_DIR}/users.sql
194239

195-
if [ "$?" -ne 0 ]; then
196-
exitWithMsg 213 "Users dump failed"
240+
if [ "$?" -ne 0 ]; then
241+
exitWithMsg 213 "Users dump failed"
242+
fi
197243
fi
198244

199-
echo "Grants ..."
200-
# Needs refactor
201-
GRANTS_SQL="select distinct concat( \"SHOW GRANTS FOR '\",user,\"'@'\",host,\"';\" ) from mysql.user WHERE user != 'root';"
202-
GRANTS_LIST=$(mysql ${MYSQL_CONN} -ANe"${GRANTS_SQL}")
203-
echo ${GRANTS_LIST} | mysql --default-character-set=utf8 --skip-comments ${MYSQL_CONN} | sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/-- \1 --/;/--/{x;p;x;}' > ${BACKUP_DIR}/grants.sql
245+
hasSkip "grants"
246+
if [ "$?" -eq 0 ]; then
247+
echo "Grants ..."
248+
# Needs refactor
249+
GRANTS_SQL="select distinct concat( \"SHOW GRANTS FOR '\",user,\"'@'\",host,\"';\" ) from mysql.user WHERE user != 'root';"
250+
GRANTS_LIST=$(mysql ${MYSQL_CONN} -ANe"${GRANTS_SQL}")
251+
echo ${GRANTS_LIST} | mysql --default-character-set=utf8 --skip-comments ${MYSQL_CONN} | sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/-- \1 --/;/--/{x;p;x;}' > ${BACKUP_DIR}/grants.sql
204252

205-
if [ "$?" -ne 0 ]; then
206-
exitWithMsg 214 "Grants dump failed"
253+
if [ "$?" -ne 0 ]; then
254+
exitWithMsg 214 "Grants dump failed"
255+
fi
256+
# Removes double backslashes > \\
257+
sed -i -e 's/\\\\//g' ${BACKUP_DIR}/grants.sql
258+
# echo -e ${GRANTS_SQL}
207259
fi
208260

209-
# Removes double backslashes > \\
210-
sed -i -e 's/\\\\//g' ${BACKUP_DIR}/grants.sql
211-
# echo -e ${GRANTS_SQL}
212261

213262
echo "Backup done !"
214263

0 commit comments

Comments
 (0)