-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenmysqlscript.sh
executable file
·400 lines (342 loc) · 10.2 KB
/
genmysqlscript.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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
#!/bin/bash
#
# Author: Joshua Chen
# Date: 2014-08-03
# Location: Shenzhen
# Description: generate a service control script for a specific mysql config file
# based on the original script
#
# functions
help()
{
echo "Usage: $(basename $0) <config file>" >&2
}
generate_script()
{
cat > $target << 'GENERATE-SCRIPT'
#!/bin/sh
#
# mysqld This shell script takes care of starting and stopping
# the MySQL subsystem (mysqld).
#
# chkconfig: - 64 36
# description: MySQL database server.
# processname: mysqld
# config: /etc/my.cnf
# pidfile: /var/run/mysqld/mysqld.pid
###################################################################
# #
# Author: Joshua Chen #
# Date: 2014-08-03 #
# Location: ShenZhen #
# Description: #
# to suit the needs of running multiple instances, #
# this script shall be generated by genmysqlscript #
# #
###################################################################
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
basedir="{{BASEDIR}}"
mysqld_safe="{{MYSQLD_SAFE}}"
mysqladmin="{{MYSQLADMIN}}"
installdb="{{INSTALLDB}}"
inst="{{INSTANCE}}"
pdefault="{{MYPRINTDEFAULT}}"
config_file="{{CONFIGFILE}}"
# Set timeouts here so they can be overridden from /etc/sysconfig/${inst}
STARTTIMEOUT=120
STOPTIMEOUT=60
[ -e /etc/sysconfig/${inst} ] && . /etc/sysconfig/${inst}
lockfile=/var/lock/subsys/${inst}
# extract value of a MySQL option from config files
# Usage: get_mysql_option SECTION VARNAME DEFAULT
# result is returned in $result
# We use my_print_defaults which prints all options from multiple files,
# with the more specific ones later; hence take the last match.
get_mysql_option(){
result=`${pdefault} -c $config_file $1 | sed -n "s/^--$2=//p" | tail -n 1`
if [ -z "$result" ]; then
# not found, use default
result="$3"
fi
}
# read the settings from the config file
get_mysql_option "mysqld mysqld_safe" datadir "/var/lib/mysql"
datadir="$result"
get_mysql_option "mysqld mysqld_safe" socket "$datadir/mysql.sock"
socketfile="$result"
test "${socketfile/\//}" = "$socketfile" && socketfile="${datadir}/${socketfile}"
get_mysql_option "mysqld mysqld_safe" log-error "/var/log/mysqld.log"
errlogfile="$result"
test "${errlogfile/\//}" = "$errlogfile" && errlogfile="${datadir}/${errlogfile}"
get_mysql_option "mysqld mysqld_safe" log-bin "${datadir}/binlog"
binlog="$result"
get_mysql_option "mysqld mysqld_safe" pid-file "/var/run/mysqld/mysqld.pid"
mypidfile="$result"
test "${mypidfile/\//}" = "$mypidfile" && mypidfile="${datadir}/${mypidfile}"
get_mysql_option "mysqld mysqld_safe" user mysql
user="$result"
get_mysql_option "mysqld mysqld_safe" basedir "$basedir"
basedir="$result"
get_mysql_option "mysqld mysqld_safe" innodb_log_group_home_dir "$datadir"
innodb_log_group_home_dir="$result"
get_mysql_option "mysqld mysqld_safe" innodb_data_home_dir "$datadir"
innodb_data_home_dir="$result"
get_mysql_option "mysqld mysqld_safe" relay-log "$datadir"
relay_log_dir="$(dirname $result)"
isrunning()
{
RESPONSE=`$mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1`
if [ $? = 0 ]; then
ret=0
elif echo "$RESPONSE" | grep -q "Access denied for user"; then
ret=0
else
ret=1
fi
return $ret
}
prepare_dirs()
{
# fail if $user not exists
if ! grep -qE "^${user}:" /etc/passwd; then
echo "user $user not exists" >&2
exit 1
fi
for dir in $datadir $(dirname $socketfile) $(dirname $errlogfile) \
$(dirname $mypidfile) $(dirname $binlog) $innodb_log_group_home_dir \
$innodb_data_home_dir $relay_log_dir
do
if [ "$dir" != "." ];then
if [ ! -e "$dir" -a ! -h "$dir" ]; then
mkdir -pv "$dir" || exit 1
fi
chown ${user}:${user} "$dir"
chmod 0755 "$dir"
[ -x /sbin/restorecon ] && /sbin/restorecon "$dir"
fi
done
}
start(){
[ -x $mysqld_safe ] || exit 5
if isrunning; then
# already running, do nothing
action $"Starting $inst: " /bin/true
ret=0
else
# prepare for start
if [ ! -d "$datadir/mysql" ] ; then
# First, make sure $datadir and other directories are there with correct permissions
prepare_dirs
# Now create the database
action $"Initializing MySQL database: " ${installdb} --defaults-file="$config_file" --basedir="$basedir"
ret=$?
chown -R ${user}:${user} "$datadir"
if [ $ret -ne 0 ] ; then
return $ret
fi
fi
chown ${user}:${user} "$datadir"
chmod 0755 "$datadir"
touch "$errlogfile"
chown ${user}:${user} "$errlogfile"
chmod 0640 "$errlogfile"
[ -x /sbin/restorecon ] && /sbin/restorecon "$errlogfile"
# Pass all the options determined above, to ensure consistent behavior.
# In many cases mysqld_safe would arrive at the same conclusions anyway
# but we need to be sure. (An exception is that we don't force the
# log-error setting, since this script doesn't really depend on that,
# and some users might prefer to configure logging to syslog.)
# Note: set --basedir to prevent probes that might trigger SELinux
# alarms, per bug #547485
$mysqld_safe --defaults-file=$config_file --basedir="$basedir" >/dev/null 2>&1 &
safe_pid=$!
# Spin for a maximum of N seconds waiting for the server to come up;
# exit the loop immediately if mysqld_safe process disappears.
# Rather than assuming we know a valid username, accept an "access
# denied" response as meaning the server is functioning.
ret=0
TIMEOUT="$STARTTIMEOUT"
while [ $TIMEOUT -gt 0 ]
do
isrunning && break;
if ! /bin/kill -0 $safe_pid 2>/dev/null; then
echo "MySQL Daemon failed to start."
ret=1
break
fi
sleep 1
let TIMEOUT=${TIMEOUT}-1
done
if [ $TIMEOUT -eq 0 ]; then
echo "Timeout error occurred trying to start MySQL Daemon."
ret=1
fi
if [ $ret -eq 0 ]; then
action $"Starting $inst: " /bin/true
touch $lockfile
else
action $"Starting $inst: " /bin/false
fi
fi
return $ret
}
stop(){
if [ ! -f "$mypidfile" ]; then
# not running; per LSB standards this is "ok"
action $"Stopping $inst: " /bin/true
return 0
fi
MYSQLPID=`cat "$mypidfile"`
if [ -n "$MYSQLPID" ]; then
/bin/kill "$MYSQLPID" &>/dev/null
ret=$?
if [ $ret -eq 0 ]; then
TIMEOUT="$STOPTIMEOUT"
while [ $TIMEOUT -gt 0 ]
do
/bin/kill -0 "$MYSQLPID" >/dev/null 2>&1 || break
sleep 1
let TIMEOUT=${TIMEOUT}-1
done
if [ $TIMEOUT -eq 0 ]; then
echo "Timeout error occurred trying to stop MySQL Daemon."
ret=1
action $"Stopping $inst: " /bin/false
else
rm -f $lockfile
rm -f "$socketfile"
action $"Stopping $inst: " /bin/true
fi
else
action $"Stopping $inst: " /bin/false
fi
else
# failed to read pidfile, probably insufficient permissions
action $"Stopping $inst: " /bin/false
ret=4
fi
return $ret
}
restart(){
stop
start
}
condrestart(){
[ -e $lockfile ] && restart || :
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status -p "$mypidfile" $inst
;;
restart)
restart
;;
condrestart|try-restart)
condrestart
;;
force-reload)
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|force-reload}"
exit 2
esac
exit $?
GENERATE-SCRIPT
}
getinput()
{
echo -n "$1 [$2]: "
read result
if [ -z "$result" ];then
result=$2
fi
}
get_instance()
{
while true
do
getinput "What name for this instance" "mysqld"
if [ -e /etc/init.d/$result ];then
echo "$result already exists, choose another one" >&2
else
break
fi
done
}
get_basedir()
{
while true
do
getinput "Where is the base dir (installation prefix)" "/usr"
if [ ! -e $result/bin/mysqld_safe ];then
echo "$result doesn't seem to be a valid base dir" >&2
else
break
fi
done
}
getexec()
{
while true
do
getinput "$1" "$2"
if [ ! -f "$result" -o ! -x "$result" ];then
echo "$result not exists or is not executable" >&2
else
break
fi
done
}
# config file must be specified and exist
if [ -z "$1" ];then
help
exit 1
fi
if [ ! -e "$1" ];then
echo "$1 not exists" >&2
exit 1
fi
# determine the absolute path name of the config file
if [ "${1#/}" = "$1" ];then
config_file="$(cd $(dirname $1); pwd)/$(basename $1)"
else
config_file="$1"
fi
get_instance
inst="$result"
target="/etc/init.d/$inst"
get_basedir
basedir=$result
getexec "Where is the mysqld_safe" "$basedir/bin/mysqld_safe"
mysqld_safe="$result"
getexec "Where is the mysqladmin" "$basedir/bin/mysqladmin"
mysqladmin="$result"
getexec "Where is the mysql_install_db" "$(find $basedir -name mysql_install_db)"
installdb="$result"
getexec "Where is the my_print_defaults" "$basedir/bin/my_print_defaults"
pdefault="$result"
# create the target script
generate_script
# customize the script
sed -i \
-e "s@{{BASEDIR}}@$basedir@g" \
-e "s@{{MYSQLD_SAFE}}@$mysqld_safe@g" \
-e "s@{{MYSQLADMIN}}@$mysqladmin@g" \
-e "s@{{INSTALLDB}}@$installdb@g" \
-e "s@{{INSTANCE}}@$inst@g" \
-e "s@{{MYPRINTDEFAULT}}@$pdefault@g" \
-e "s@{{CONFIGFILE}}@$config_file@g" \
$target
chmod 755 $target
chkconfig --add $inst