]> git.pld-linux.org Git - packages/mysql.git/blob - mysql.init
- use log-error param for stderr capture, this way we can rotate the error log
[packages/mysql.git] / mysql.init
1 #!/bin/sh
2 #
3 # mysql         A very fast and reliable SQL database engine
4 #
5 # chkconfig:    2345 84 25
6 #
7 # description:  A very fast and reliable SQL database engine.
8 #
9 # $Id$
10
11 # Source function library
12 . /etc/rc.d/init.d/functions
13
14 # Get network config
15 . /etc/sysconfig/network
16
17 # Get service config
18 if [ -f /etc/sysconfig/mysql ]; then
19         . /etc/sysconfig/mysql
20 else
21         nls "Error: %s not found" /etc/sysconfig/mysql
22         nls "%s can't be run." MySQL
23         exit 1
24 fi
25
26 if [ -n "$MYSQL_DB_CLUSTERS" ]; then
27         nls "Warning: MYSQL_DB_CLUSTERS is set. It's obsolete. Use %s instead." /etc/mysql/clusters.conf
28 fi
29
30 if [ -f /etc/mysql/clusters.conf ]; then
31         MYSQL_DB_CLUSTERS=$(awk -F= '!/^#/{print $2}' /etc/mysql/clusters.conf)
32         if [ -z "$MYSQL_DB_CLUSTERS"  ]; then
33                 nls "Warning: there are no configured clusters."
34         fi
35
36 else
37         nls "Warning: Missing clusters config file %s" /etc/mysql/clusters.conf
38         if [ -z "$MYSQL_DB_CLUSTERS"  ]; then
39                 nls "Warning: there are no configured clusters."
40                 nls "Using default cluster /var/lib/mysql (compatibility mode)"
41                 MYSQL_DB_CLUSTERS=/var/lib/mysql
42         fi
43 fi
44
45
46 # Check that networking is up
47 if is_yes "${NETWORKING}"; then
48         if [ ! -f /var/lock/subsys/network -a "$1" != stop -a "$1" != status -a "$1" != init ]; then
49                 msg_network_down MySQL
50                 exit 1
51         fi
52 else
53         exit 0
54 fi
55
56 action="$1"
57
58 # any db cluster as command line argument?
59 if [ $# -gt 1 ]; then
60         shift
61         # perform action for specified clusters only
62         for a in "$@"; do
63                 # try auto resolving from /etc/mysql/clusters.conf
64                 if [[ "$a" != /* ]]; then
65                         m=$(awk -va="$a" -F= 'substr($0, 1, length(a)) == a {print $1}' /etc/mysql/clusters.conf)
66                         if [ -z "$m" ]; then
67                                 echo >&2 "Cluster name '$a' did not match anything!"
68                                 exit 1
69                         fi
70                         if [ $(echo "$m" | wc -l) -gt 1 ]; then
71                                 echo >&2 "Cluster name '$a' ambiguous:" $m
72                                 exit 1
73                         fi
74                         a=$(awk -va="$a" -F= 'substr($0, 1, length(a)) == a {print $2}' /etc/mysql/clusters.conf)
75                 fi
76                 DB_CLUSTERS="$DB_CLUSTERS $a"
77         done
78 else
79         DB_CLUSTERS="$MYSQL_DB_CLUSTERS"
80 fi
81
82 # global error log, if mysqld.conf hasn't migrated to log-error style
83 MYSQL_ERRLOG=/var/log/mysql/mysqld.log
84 MYSQL_STOP_WAIT_TIME=${MYSQL_STOP_WAIT_TIME:-900}
85
86 #
87 # Useful functions.
88 #
89
90 #
91 # check for mysql status
92 #
93 # arguments:
94 # $1 - db cluster
95 # $2 - start|stop
96 #
97 # sets variables:
98 # MYSQL_STATUS = starting | running | not running | died
99 # MYSQL_PID    = pid of mysqld process
100 #
101 mysqlstatus() {
102         clusterdir="$1"
103         mode="$2"
104         
105         mysqlgetconfig "$clusterdir"
106
107         MYSQL_STATUS="not running"
108         MYSQL_PID="unknown"
109         MYSQL_PIDFILE_PID=""
110         MYSQL_GREP_PID=""
111
112         if [ -f "$MYSQL_PIDFILE" ]; then
113                 MYSQL_PIDFILE_PID=$(cat "$MYSQL_PIDFILE")
114         fi
115         
116         if [ -n "$MYSQL_PIDFILE_PID" ]; then
117                 MYSQL_PID=$MYSQL_PIDFILE_PID
118                 if [ ! -d "/proc/$MYSQL_PID" ]; then
119                         MYSQL_STATUS="died"
120                         return
121                 elif (grep -qa "$MYSQL_PIDFILE" /proc/$MYSQL_PID/cmdline 2> /dev/null); then
122                         MYSQL_STATUS="running"
123                         return
124                 fi
125         fi
126
127         if [ "$mode" = "start" ]; then
128                 MYSQL_GREP_PID=$(grep -lE "^/usr/sbin/mysqld.*${MYSQL_PIDFILE}" /proc/[0-9]*/cmdline 2> /dev/null | awk -F "/" '{ print $3; exit; }')
129                 if [ -n "$MYSQL_GREP_PID" ]; then
130                         MYSQL_PID=$MYSQL_GREP_PID
131                         if grep -qa "$MYSQL_PIDFILE" /proc/$MYSQL_PID/cmdline 2> /dev/null; then
132                                 if [ -f "$MYSQL_PIDFILE" ]; then
133                                         MYSQL_PIDFILE_PID=$(cat "$MYSQL_PIDFILE")
134                                 fi
135                                 if [ -n "$MYSQL_PIDFILE_PID" ]; then
136                                         MYSQL_PID=$MYSQL_PIDFILE_PID
137                                         MYSQL_STATUS="running"
138                                         return
139                                 else
140                                         MYSQL_STATUS="starting"
141                                         return
142                                 fi
143                         fi
144                 fi
145         fi
146
147         # else default, "not running"
148 }
149
150 # get mysql configuration in variables
151 # MYSQL_CONFIG MYSQL_DATA_DIR MYSQL_USER MYSQL_PIDFILE
152 #
153 # arguments
154 # $1 - db cluster
155
156 mysqlgetconfig() {
157         clusterdir="$1"
158
159         # emulate old behaviour if only one cluster specified
160         if [ "$clusterdir" = "$MYSQL_DB_CLUSTERS" -a "$clusterdir" = "/var/lib/mysql" -a -f /etc/mysqld.conf ]; then
161                 MYSQL_RA_COMPAT=yes
162                 config_file=/etc/mysqld.conf
163         else
164                 config=$(awk -F= -vclusterdir="$clusterdir" '!/^#/{ if (clusterdir == $2) print $1}' /etc/mysql/clusters.conf)
165                 if [[ $config = /* ]]; then
166                         config_file="$config"
167                 elif [ -f "/etc/mysql/$config" ]; then
168                         config_file="/etc/mysql/$config"
169                 else
170                         config_file="$clusterdir/mysqld.conf"
171                 fi
172         fi
173
174         MYSQL_CLUSTER_DIR="$clusterdir"
175
176         if [ -z "$config_file" ]; then
177                 nls "Error: Can't find config file for %s cluster" "$clusterdir"
178                 exit 6
179         else
180                 MYSQL_CONFIG="$config_file"
181         fi
182
183         if [ ! -f "$config_file" ]; then
184                 nls "Error: config file %s not found" "$config_file"
185                 nls "MySQL can't be run. Did you initialize DB by doing \`$0 init'?"
186                 exit 6
187         fi
188
189         eval `awk '
190 /^[ \t]*\[.*\][ \t]*$/ {
191         match($0,/\[.*\]/)
192         section=substr($0, RSTART + 1, RSTART + RLENGTH - 3)
193 }
194 section == "mysqld" && $2 ~ "=" {
195         if ($1 == "datadir") {
196                 printf("MYSQL_DATA_DIR=%s;", $3)
197         } else if ($1 == "user") {
198                 printf("MYSQL_USER=%s;", $3)
199         } else if ($1 == "pid-file") {
200                 printf("MYSQL_PIDFILE=%s;", $3)
201         } else if ($1 == "socket") {
202                 printf("MYSQL_SOCKET=%s;", $3)
203         }
204 }
205 ' $config_file`
206
207
208         if is_yes "$MYSQL_RA_COMPAT"; then
209                 MYSQL_DATA_DIR_SUB=""
210         else
211                 MYSQL_DATA_DIR_SUB="/mysqldb"
212         fi
213
214         if [ -z "$MYSQL_DATA_DIR" -o "$MYSQL_DATA_DIR" != "${clusterdir}${MYSQL_DATA_DIR_SUB}/db" ]; then
215                 nls "Error: datadir specified in %s should be %s" "$config_file" "$clusterdir${MYSQL_DATA_DIR_SUB}/db"
216                 nls " MySQL can't be run."
217                 exit 6
218         fi
219
220         if [ -z "$MYSQL_PIDFILE" -o "$MYSQL_PIDFILE" != "$clusterdir${MYSQL_DATA_DIR_SUB}/mysql.pid" ]; then
221                 nls "Error: pid-file specified in %s should be %s" "$config_file" "$clusterdir${MYSQL_DATA_DIR_SUB}/mysql.pid"
222                 nls " MySQL can't be run."
223                 exit 6
224         fi
225
226         if [ -z $MYSQL_USER ]; then
227                 echo "$(nls 'MySQL user not configured properly')"'!' >&2
228                 nls "Edit %s and configure it." "$config_file" >&2
229                 exit 6
230         fi
231 }
232
233 # start mysql
234 mysqlstart() {
235         clusterdir="$1"
236         mysqlgetconfig "$clusterdir"
237         if [ ! -d "$MYSQL_DATA_DIR/mysql" ]; then
238                 nls "MySQL cluster %s not initialized." "$clusterdir"
239                 nls "Try \`%s init %s' before start." "$0" "$clusterdir"
240                 exit 6
241         fi
242
243         msg_starting "MySQL $clusterdir"
244         busy
245         [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
246         rm -f "$MYSQL_PIDFILE"
247
248         if [ "$(grep -c ^log-error $MYSQL_CONFIG)" -lt 1 ]; then
249                 # error log not defined in config file. add one
250                 MYSQL_OPTIONS="$MYSQL_OPTIONS --log-error=$MYSQL_ERRLOG"
251         fi
252
253         TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} \
254                 /usr/bin/setsid /usr/sbin/mysqld \
255                         --defaults-file=$MYSQL_CONFIG \
256                         --datadir=$MYSQL_DATA_DIR \
257                         --pid-file=$MYSQL_PIDFILE \
258                         $MYSQL_OPTIONS &
259         pid=$!
260
261         sleep 0.1
262         mysqlstatus "$clusterdir" start
263         # it takes longer for mysqld to start and create pidfile if it has to recover innodb transactions
264         if [ "$MYSQL_STATUS" = "starting" ]; then
265                 echo ""
266                 show "Waiting for MySQL to start"
267                 busy
268
269                 # while the pid is running, mysql is starting up
270                 # if the pidfile was created, it started up successfully
271                 # if either case fails we break and report status
272                 while true; do
273                         [ -d /proc/$pid ] || break
274                         [ -f "$MYSQL_PIDFILE" ] && break
275                         sleep 0.2
276                 done
277         fi
278
279         mysqlstatus "$clusterdir" start
280         if [ "$MYSQL_STATUS" = "running" -a "$MYSQL_PID" != "unknown" ]; then
281                 ok
282         elif [ "$MYSQL_STATUS" = "died" ]; then
283                 RETVAL=1
284                 died
285         else
286                 RETVAL=1
287                 fail
288         fi
289 }
290
291 # stop mysql
292 mysqlstop() {
293         clusterdir="$1"
294         mysqlstatus "$clusterdir" stop
295         msg_stopping "MySQL $clusterdir"
296         busy
297
298         # try graceful shutdown -- send shutdown command
299         # requires mysql_sysadmin user proper privs
300         /usr/bin/mysqladmin --defaults-file=$MYSQL_CONFIG ${MYSQL_SOCKET:+--socket=$MYSQL_SOCKET} shutdown >/dev/null 2>&1
301         mysqlstatus "$clusterdir" stop
302
303         if [ "$MYSQL_PID" != "unknown" ]; then
304                 kill -TERM "$MYSQL_PID" 2> /dev/null
305                 for nr in $(seq 1 $(($MYSQL_STOP_WAIT_TIME*10))); do
306                         [ -d "/proc/$MYSQL_PID" ] || break
307                         sleep 0.1
308                 done
309         fi
310         
311         mysqlstatus "$clusterdir" stop
312         if [ "$MYSQL_STATUS" = "died" ]; then
313                 died
314         elif [ "$MYSQL_STATUS" = "running" -o "$MYSQL_STATUS" = "starting" ]; then
315                 fail
316         else
317                 ok
318         fi
319 }
320
321 #
322 # check for running mysql instances; if any instance is running then
323 # create subsys lock file
324 #
325 mysqlsubsys() {
326         # check for every defined db cluster in sysconfig file
327         for mysqldir in $DB_CLUSTERS; do
328                 mysqlstatus "$mysqldir"
329                 if [ "$MYSQL_STATUS" = "running" ]; then
330                         touch /var/lock/subsys/mysql
331                         return
332                 fi
333         done
334         rm -f /var/lock/subsys/mysql
335 }
336
337 mysqlinit() {
338         clusterdir="$1"
339
340         if [ -f /etc/mysqld.conf ]; then
341                 nls "Running in \`no cluster compat' mode: can't initialize database."
342                 nls "Move /etc/mysqld.conf away and rerun \`$0 init' (new config will be in $clusterdir)."
343                 exit 1
344         fi
345
346         if [ -f "$clusterdir/mysqld.conf" ]; then
347                 mysqlgetconfig "$clusterdir"
348         else
349                 MYSQL_USER="mysql"
350                 MYSQL_CLUSTER_DIR="$clusterdir"
351                 MYSQL_DATA_DIR="$clusterdir/mysqldb/db"
352                 MYSQL_PIDFILE="$clusterdir/mysqldb/mysql.pid"
353                 MYSQL_SOCKET="$clusterdir/mysqldb/mysql.sock"
354
355                 # this $MYSQL_CONFIG will be created later
356                 MYSQL_CONFIG="$MYSQL_CLUSTER_DIR/mysqld.conf"
357         fi
358
359         show "Initializing cluster %s" "$clusterdir"; echo
360
361         # Check if not exist init database
362         if [ -d "$MYSQL_DATA_DIR/mysql" ]; then
363                 nls "Seems that database is initialized now. Remove by hand %s" "$MYSQL_DATA_DIR/mysql"
364                 nls "before initializing database."
365                 nls "For now skipping cluster %s." "$clusterdir"
366                 return
367         fi
368
369         show "Installing MySQL system tables for $MYSQL_DATA_DIR"
370         busy
371         TMP=/tmp TMPDIR=/tmp
372
373         mkdir -p "$MYSQL_DATA_DIR" > /dev/null 2>&1
374         # Using mysql:mysql for MYSQL_CLUSTER_DIR is creating SECURITY hole, root:root is proper
375         chown root:root "$MYSQL_CLUSTER_DIR"
376         chown mysql:mysql "$MYSQL_CLUSTER_DIR/mysqldb" "$MYSQL_DATA_DIR" > /dev/null 2>&1
377         chmod 751 "$MYSQL_CLUSTER_DIR" "$MYSQL_CLUSTER_DIR/mysqldb"
378
379         if [ -f /usr/share/mysql/mysqld.conf -a ! -f "$MYSQL_CLUSTER_DIR/mysqld.conf" ]; then
380             sed -e "
381                 s#\(datadir.*\)=.*#\1= $MYSQL_DATA_DIR#g;
382                 s#\(pid-file.*\)=.*#\1= $MYSQL_PIDFILE#g;
383                 s#\(socket.*\)=.*#\1= $MYSQL_SOCKET#g;
384                 s#@clusterdir@#$MYSQL_CLUSTER_DIR#g;
385                 " /usr/share/mysql/mysqld.conf > "$MYSQL_CLUSTER_DIR/mysqld.conf"
386             chown root:root "$MYSQL_CLUSTER_DIR/mysqld.conf"
387             chmod 640 "$MYSQL_CLUSTER_DIR/mysqld.conf"
388         fi
389
390         if [ ! -e /var/lib/mysql/mysql.sock ] || [ -L /var/lib/mysql/mysql.sock ] && [ -z "$(readlink /var/lib/mysql/mysql.sock)" ]; then
391                 sock=${MYSQL_SOCKET#/var/lib/mysql/} # make it relative if possible
392             ln -s "$sock" /var/lib/mysql/mysql.sock
393         fi
394
395         cat > $MYSQL_DATA_DIR/mysql-init.sql <<-EOF
396                 CREATE DATABASE mysql;
397                 use mysql;
398                 $(cat /usr/share/mysql/mysql_system_tables.sql)
399                 $(sed -e "/@current_hostname/d" /usr/share/mysql/mysql_system_tables_data.sql)
400 EOF
401
402         ok=0
403         /usr/sbin/mysqld --bootstrap --skip-grant-tables \
404                 --datadir=$MYSQL_DATA_DIR --user=$MYSQL_USER \
405                 --slave-load-tmpdir=$MYSQL_DATA_DIR --tmpdir=$MYSQL_DATA_DIR < \
406                 $MYSQL_DATA_DIR/mysql-init.sql 2>> /var/log/mysql/err && ok=1
407         [ -f $MYSQL_DATA_DIR/mysql/host.frm ] || ok=0
408
409         if [ "$ok" = 1 ]; then
410                 rm -f $MYSQL_DATA_DIR/mysql-init.sql
411                 ok
412                 cat << END_OF_MSG
413
414 PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL USERS!
415 This is done, after starting database, in the order shown,
416 with:
417
418 For 'mysql_sysadmin' (RELOAD and SHUTDOWN privileges):
419 echo "update mysql.user set password=password('newpassword') where user='mysql_sysadmin'; FLUSH PRIVILEGES;" | mysql -u mysql -S $MYSQL_SOCKET
420
421 For 'mysql' user (ALL privileges, DB admin):
422 echo "update mysql.user set password=password('newpassword') where user='mysql'; FLUSH PRIVILEGES;" | mysql -u mysql -S $MYSQL_SOCKET
423
424 NOTE: mysql_sysadmin password should be placed to $MYSQL_CONFIG in
425 mysqladmin section. See the manual for more instructions.
426 (This user is used at logs rotation and server shutdown)
427
428 END_OF_MSG
429                 show "Filling help tables..."
430                 ok=0
431                 ( echo "use mysql;"; cat /usr/share/mysql/fill_help_tables.sql ) | \
432                         /usr/sbin/mysqld --bootstrap --skip-grant-tables \
433                         --datadir=$MYSQL_DATA_DIR --user=$MYSQL_USER \
434                         --slave-load-tmpdir=$MYSQL_DATA_DIR --tmpdir=$MYSQL_DATA_DIR \
435                         2>> /var/log/mysql/err && ok=1
436                 if [ "$ok" = 1 ]; then
437                         ok
438                 else
439                         cat << END_OF_MSG
440
441 WARNING: HELP FILES ARE NOT COMPLETELY INSTALLED!
442 The "HELP" command might not work properly.
443
444 END_OF_MSG
445                 fi
446         else
447                 fail
448                 cat << END_OF_MSG
449 Installation of grant tables FAILED!
450
451 The initialization SQL script was preserved at $MYSQL_DATA_DIR/mysql-init.sql
452
453 Examine the logs in /var/log/mysql for more information.  You can
454 also try to start the mysqld daemon with:
455
456 /usr/sbin/mysqld --skip-grant &
457
458 You can use the command line tool mysql to connect to the mysql
459 database and look at the grant tables:
460
461 shell> mysql -u mysql mysql
462 mysql> show tables
463
464 Try 'mysqld --help' if you have problems with paths. Setting on
465 logging in /etc/mysqld.conf gives you a log in /var/log/mysql/log that
466 may be helpful. The latest information about MySQL is available on the
467 web at http://www.mysql.com/.
468
469 Please check PLD Linux ftp site for newer versions of this package.
470
471 Please consult the MySQL manual section: 'Problems running
472 mysql_install_db', and the manual section that describes problems on
473 your OS.  Another information source is the MySQL email archive.
474 Please check all of the above before mailing us!  And if you do mail
475 us, you MUST use the mysqlbug script!
476
477 END_OF_MSG
478                 exit 1
479         fi
480 }
481
482 #
483 # End of useful functions.
484 #
485
486 start() {
487         for mysqldir in $DB_CLUSTERS; do
488                 mysqlstatus "$mysqldir" start
489                 if [ "$MYSQL_STATUS" = "running" ]; then
490                         msg_already_running "MySQL $mysqldir"
491                 else
492                         mysqlstart "$mysqldir"
493                 fi
494         done
495         mysqlsubsys
496 }
497
498 stop() {
499         for mysqldir in $DB_CLUSTERS; do
500                 mysqlstatus "$mysqldir" stop
501                 if [ "$MYSQL_STATUS" = "not running" ]; then
502                         msg_not_running "MySQL $mysqldir"
503                 else
504                         mysqlstop "$mysqldir"
505                 fi
506         done
507         mysqlsubsys
508 }
509
510 condrestart() {
511         if [ -f /var/lock/subsys/mysql ]; then
512                 stop
513                 start
514         else
515                 msg_not_running "MySQL"
516                 RETVAL=$1
517         fi
518 }
519
520 RETVAL=0
521 case "$action" in
522   start)
523         start
524         ;;
525   stop)
526         stop
527         ;;
528   restart)
529         stop
530         start
531         ;;
532   try-restart)
533         condrestart 0
534         ;;
535   force-reload)
536         condrestart 7
537         ;;
538   status)
539         for mysqldir in $DB_CLUSTERS; do
540                 mysqlstatus "$mysqldir"
541                 if [ "$MYSQL_STATUS" = "running" ]; then
542                         show "MySQL cluster %s, PID %s" "$mysqldir" "$MYSQL_PID"
543                         pids="$pids/$MYSQL_PID/"
544                         progress "$MYSQL_STATUS"
545                 else
546                         show "MySQL cluster %s" "$mysqldir"
547                         progress "$MYSQL_STATUS" "$CFAIL"
548                 fi
549                 echo
550         done
551
552         for pid in $(/sbin/pidof mysqld); do
553                 if [[ $pids != */$pid/* ]]; then
554                         running="$running $pid"
555                 fi
556         done
557
558         if [ $# -gt 1 -a "$running" ]; then
559                 nls "Warning: MySQL Daemon processes not under clusters.conf control:"
560                 # see if we can display their status
561                 for pid in $running; do
562                         datadir=$(cat /proc/$pid/cmdline | tr '\0' '\n' | fgrep -- --datadir=)
563                         datadir=${datadir#--datadir=} # strip --datadir
564                         mysqldir=${datadir%/mysqldb/db} # strip /mysqldb/db
565                         mysqlstatus "$mysqldir"
566                         if [ "$MYSQL_STATUS" = "running" ]; then
567                                 show "MySQL cluster %s, PID %s" "$mysqldir" "$pid"
568                                 progress "$MYSQL_STATUS"
569                         else
570                                 show "MySQL cluster %s" "$mysqldir"
571                                 progress "$MYSQL_STATUS" "$CFAIL"
572                         fi
573                         echo
574                 done
575         fi
576         ;;
577   init)
578         for mysqldir in $DB_CLUSTERS; do
579                 mysqlinit "$mysqldir"
580         done
581         exit $?
582         ;;
583   flush-logs)
584         for mysqldir in $DB_CLUSTERS; do
585             mysqlgetconfig "$mysqldir"
586                 # just if mysqld is really running
587                 if /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" ping >/dev/null 2>&1; then
588                         /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" flush-logs
589                 fi
590         done
591         ;;
592   *)
593         msg_usage "$0 {start|stop|init|restart|try-restart|force-reload|status}"
594         exit 3
595 esac
596
597 exit $RETVAL
This page took 0.190724 seconds and 4 git commands to generate.