]> git.pld-linux.org Git - packages/mysql.git/blob - mysql.init
- update mysqld.conf path in init fail message, don't suggest to use mysqlbug script...
[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 \
404                 --defaults-file=$MYSQL_CLUSTER_DIR/mysqld.conf \
405                 --bootstrap \
406                 --skip-grant-tables \
407                 --datadir=$MYSQL_DATA_DIR \
408                 --user=$MYSQL_USER \
409                 --slave-load-tmpdir=$MYSQL_DATA_DIR \
410                 --tmpdir=$MYSQL_DATA_DIR \
411                 --log-error=$MYSQL_ERRLOG \
412                 < $MYSQL_DATA_DIR/mysql-init.sql && ok=1
413         [ -f $MYSQL_DATA_DIR/mysql/host.frm ] || ok=0
414
415         if [ "$ok" = 1 ]; then
416                 rm -f $MYSQL_DATA_DIR/mysql-init.sql
417                 ok
418                 cat << END_OF_MSG
419
420 PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL USERS!
421 This is done, after starting database, in the order shown,
422 with:
423
424 For 'mysql_sysadmin' (RELOAD and SHUTDOWN privileges):
425 echo "update mysql.user set password=password('newpassword') where user='mysql_sysadmin'; FLUSH PRIVILEGES;" | mysql -u mysql -S $MYSQL_SOCKET
426
427 For 'mysql' user (ALL privileges, DB admin):
428 echo "update mysql.user set password=password('newpassword') where user='mysql'; FLUSH PRIVILEGES;" | mysql -u mysql -S $MYSQL_SOCKET
429
430 NOTE: mysql_sysadmin password should be placed to $MYSQL_CONFIG in
431 mysqladmin section. See the manual for more instructions.
432 (This user is used at logs rotation and server shutdown)
433
434 END_OF_MSG
435                 show "Filling help tables..."
436                 ok=0
437                 ( echo "use mysql;"; cat /usr/share/mysql/fill_help_tables.sql ) | \
438                         /usr/sbin/mysqld --bootstrap --skip-grant-tables \
439                         --datadir=$MYSQL_DATA_DIR --user=$MYSQL_USER \
440                         --slave-load-tmpdir=$MYSQL_DATA_DIR --tmpdir=$MYSQL_DATA_DIR --log-error=$MYSQL_ERRLOG \
441                         && ok=1
442                 if [ "$ok" = 1 ]; then
443                         ok
444                 else
445                         cat << END_OF_MSG
446
447 WARNING: HELP FILES ARE NOT COMPLETELY INSTALLED!
448 The "HELP" command might not work properly.
449
450 END_OF_MSG
451                 fi
452         else
453                 fail
454                 cat << END_OF_MSG
455 Installation of grant tables FAILED!
456
457 The initialization SQL script was preserved at $MYSQL_DATA_DIR/mysql-init.sql
458
459 Examine the logs in /var/log/mysql for more information.  You can
460 also try to start the mysqld daemon with:
461
462 /usr/sbin/mysqld --skip-grant &
463
464 You can use the command line tool mysql to connect to the mysql
465 database and look at the grant tables:
466
467 shell> mysql -u mysql mysql
468 mysql> show tables
469
470 Try 'mysqld --help' if you have problems with paths. Setting on
471 logging in $MYSQL_DATA_DIR/mysqld.conf gives you a log in /var/log/mysql/query.log that
472 may be helpful. The latest information about MySQL is available on the
473 web at http://www.mysql.com/.
474
475 Please check PLD Linux ftp site for newer versions of this package.
476
477 Please consult the MySQL manual section: 'Problems running
478 mysql_install_db', and the manual section that describes problems on
479 your OS.  Another information source is the MySQL email archive.
480
481 END_OF_MSG
482                 exit 1
483         fi
484 }
485
486 #
487 # End of useful functions.
488 #
489
490 start() {
491         for mysqldir in $DB_CLUSTERS; do
492                 mysqlstatus "$mysqldir" start
493                 if [ "$MYSQL_STATUS" = "running" ]; then
494                         msg_already_running "MySQL $mysqldir"
495                 else
496                         mysqlstart "$mysqldir"
497                 fi
498         done
499         mysqlsubsys
500 }
501
502 stop() {
503         for mysqldir in $DB_CLUSTERS; do
504                 mysqlstatus "$mysqldir" stop
505                 if [ "$MYSQL_STATUS" = "not running" ]; then
506                         msg_not_running "MySQL $mysqldir"
507                 else
508                         mysqlstop "$mysqldir"
509                 fi
510         done
511         mysqlsubsys
512 }
513
514 condrestart() {
515         if [ -f /var/lock/subsys/mysql ]; then
516                 stop
517                 start
518         else
519                 msg_not_running "MySQL"
520                 RETVAL=$1
521         fi
522 }
523
524 RETVAL=0
525 case "$action" in
526   start)
527         start
528         ;;
529   stop)
530         stop
531         ;;
532   restart)
533         stop
534         start
535         ;;
536   try-restart)
537         condrestart 0
538         ;;
539   force-reload)
540         condrestart 7
541         ;;
542   status)
543         for mysqldir in $DB_CLUSTERS; do
544                 mysqlstatus "$mysqldir"
545                 if [ "$MYSQL_STATUS" = "running" ]; then
546                         show "MySQL cluster %s, PID %s" "$mysqldir" "$MYSQL_PID"
547                         pids="$pids/$MYSQL_PID/"
548                         progress "$MYSQL_STATUS"
549                 else
550                         show "MySQL cluster %s" "$mysqldir"
551                         progress "$MYSQL_STATUS" "$CFAIL"
552                 fi
553                 echo
554         done
555
556         for pid in $(/sbin/pidof mysqld); do
557                 if [[ $pids != */$pid/* ]]; then
558                         running="$running $pid"
559                 fi
560         done
561
562         if [ $# = 1 -a "$running" ]; then
563                 nls "Warning: MySQL Daemon processes not under clusters.conf control:"
564                 # see if we can display their status
565                 for pid in $running; do
566                         datadir=$(cat /proc/$pid/cmdline | tr '\0' '\n' | fgrep -- --datadir=)
567                         datadir=${datadir#--datadir=} # strip --datadir
568                         mysqldir=${datadir%/mysqldb/db} # strip /mysqldb/db
569                         mysqlstatus "$mysqldir"
570                         if [ "$MYSQL_STATUS" = "running" ]; then
571                                 show "MySQL cluster %s, PID %s" "$mysqldir" "$pid"
572                                 progress "$MYSQL_STATUS"
573                         else
574                                 show "MySQL cluster %s" "$mysqldir"
575                                 progress "$MYSQL_STATUS" "$CFAIL"
576                         fi
577                         echo
578                 done
579         fi
580         ;;
581   init)
582         for mysqldir in $DB_CLUSTERS; do
583                 mysqlinit "$mysqldir"
584         done
585         exit $?
586         ;;
587   flush-logs)
588         for mysqldir in $DB_CLUSTERS; do
589             mysqlgetconfig "$mysqldir"
590                 # just if mysqld is really running
591                 if /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" ping >/dev/null 2>&1; then
592                         /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" flush-logs
593                 fi
594         done
595         ;;
596   *)
597         msg_usage "$0 {start|stop|init|restart|try-restart|force-reload|status}"
598         exit 3
599 esac
600
601 exit $RETVAL
This page took 0.199933 seconds and 3 git commands to generate.