]> git.pld-linux.org Git - packages/mysql.git/blob - mysql.init
- detect if mysql tables creation fails by checking mysql.host table and leave mysql...
[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 # Source function library
10 . /etc/rc.d/init.d/functions
11
12 # Get network config
13 . /etc/sysconfig/network
14
15 # Get service config
16 if [ -f /etc/sysconfig/mysql ]; then
17         . /etc/sysconfig/mysql
18 else
19         nls "Error: %s not found" /etc/sysconfig/mysql
20         nls "%s can't be run." MySQL
21         exit 1
22 fi
23
24 [ -z "$BASE_TABLETYPE" ] && BASE_TABLETYPE="MyISAM"
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 MYSQL_ERRLOG=/var/log/mysql/err
83 MYSQL_START_WAIT_TIME=${MYSQL_START_WAIT_TIME:-15}
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         TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} /usr/bin/setsid /usr/sbin/mysqld --defaults-file=$MYSQL_CONFIG --datadir=$MYSQL_DATA_DIR --pid-file=$MYSQL_PIDFILE $MYSQL_OPTIONS >> $MYSQL_ERRLOG 2>&1 &
248         sleep 0.2
249         mysqlstatus "$clusterdir" start
250         # it takes longer for mysqld to start and create pidfile if it has to recover innodb transactions
251         if [ "$MYSQL_STATUS" = "starting" ]; then
252                 for nr in $(seq 1 $(($MYSQL_START_WAIT_TIME*10))); do
253                         [ -f "$MYSQL_PIDFILE" ] && break
254                         sleep 0.1
255                 done
256         fi
257
258         mysqlstatus "$clusterdir" start
259         if [ "$MYSQL_STATUS" = "running" -a "$MYSQL_PID" != "unknown" ]; then
260                 ok
261         elif [ "$MYSQL_STATUS" = "died" ]; then
262                 RETVAL=1
263                 died
264         else
265                 RETVAL=1
266                 fail
267         fi
268 }
269
270 # stop mysql
271 mysqlstop() {
272         clusterdir="$1"
273         mysqlstatus "$clusterdir" stop
274         msg_stopping "MySQL $clusterdir"
275         busy
276
277         # try graceful shutdown -- send shutdown command
278         # requires mysql_logrotate user proper privs
279         /usr/bin/mysqladmin --defaults-file=$MYSQL_CONFIG ${MYSQL_SOCKET:+--socket=$MYSQL_SOCKET} shutdown >/dev/null 2>&1
280         mysqlstatus "$clusterdir" stop
281
282         if [ "$MYSQL_PID" != "unknown" ]; then
283                 kill -TERM "$MYSQL_PID" 2> /dev/null
284                 for nr in $(seq 1 $(($MYSQL_STOP_WAIT_TIME*10))); do
285                         [ -d "/proc/$MYSQL_PID" ] || break
286                         sleep 0.1
287                 done
288         fi
289         
290         mysqlstatus "$clusterdir" stop
291         if [ "$MYSQL_STATUS" = "died" ]; then
292                 died
293         elif [ "$MYSQL_STATUS" = "running" -o "$MYSQL_STATUS" = "starting" ]; then
294                 fail
295         else
296                 ok
297         fi
298 }
299
300 #
301 # check for running mysql instances; if any instance is running then
302 # create subsys lock file
303 #
304 mysqlsubsys() {
305         # check for every defined db cluster in sysconfig file
306         for mysqldir in $DB_CLUSTERS; do
307                 mysqlstatus "$mysqldir"
308                 if [ "$MYSQL_STATUS" = "running" ]; then
309                         touch /var/lock/subsys/mysql
310                         return
311                 fi
312         done
313         rm -f /var/lock/subsys/mysql
314 }
315
316 mysqlinit() {
317         clusterdir="$1"
318
319         if [ -f /etc/mysqld.conf ]; then
320                 nls "Running in \`no cluster compat' mode: can't initialize database."
321                 nls "Move /etc/mysqld.conf away and rerun \`$0 init' (new config will be in $clusterdir)."
322                 exit 1
323         fi
324
325         if [ -f "$clusterdir/mysqld.conf" ]; then
326                 mysqlgetconfig "$clusterdir"
327         else
328                 MYSQL_USER="mysql"
329                 MYSQL_CLUSTER_DIR="$clusterdir"
330                 MYSQL_DATA_DIR="$clusterdir/mysqldb/db"
331                 MYSQL_PIDFILE="$clusterdir/mysqldb/mysql.pid"
332                 MYSQL_SOCKET="$clusterdir/mysqldb/mysql.sock"
333
334                 # this $MYSQL_CONFIG will be created later
335                 MYSQL_CONFIG="$MYSQL_CLUSTER_DIR/mysqld.conf"
336         fi
337
338         nls "Initializing cluster %s" "$clusterdir"
339
340         # Check if not exist init database
341         if [ -d "$MYSQL_DATA_DIR/mysql" ]; then
342                 nls "Seems that database is initialized now. Remove by hand %s" "$MYSQL_DATA_DIR/mysql"
343                 nls "before initializing database."
344                 nls "For now skipping cluster %s." "$clusterdir"
345                 return
346         fi
347
348         show "Creating privilege mysql tables for $MYSQL_DATA_DIR"
349         busy
350         TMP=/tmp TMPDIR=/tmp
351
352         # Install this in the user table, too
353         hostname="`hostname --fqdn 2> /dev/null | tr -d '[:space:]'`"
354         [ -z "$hostname" ] && hostname="localhost-unknown"
355
356         # Check if hostname is valid
357         if [ -z "$hostname" ]; then
358                 deltext
359                 fail
360                 nls "Sorry, the host name is not configured."
361                 nls "Please configure the 'hostname' command to return a hostname."
362                 exit 1
363         elif ! hostname -i >/dev/null 2>&1; then
364                 deltext
365                 fail
366                 nls "Sorry, the host '%s' could not be looked up." "$hostname"
367                 nls "Please configure the 'hostname' command to return a correct hostname."
368                 exit 1
369         fi
370
371         mkdir -p "$MYSQL_DATA_DIR"
372         # Using mysql:mysql for MYSQL_CLUSTER_DIR is creating SECURITY hole, root:root is proper
373         chown root:root "$MYSQL_CLUSTER_DIR"
374     chown mysql:mysql "$MYSQL_CLUSTER_DIR/mysqldb" "$MYSQL_DATA_DIR" > /dev/null 2>&1
375         chmod 751 "$MYSQL_CLUSTER_DIR" "$MYSQL_CLUSTER_DIR/mysqldb"
376
377         if [ -f /usr/share/mysql/mysqld.conf -a ! -f "$MYSQL_CLUSTER_DIR/mysqld.conf" ]; then
378             sed -e "
379                 s#\(datadir.*\)=.*#\1= $MYSQL_DATA_DIR#g;
380                 s#\(pid-file.*\)=.*#\1= $MYSQL_PIDFILE#g;
381                 s#\(socket.*\)=.*#\1= $MYSQL_SOCKET#g;
382                 s#@clusterdir@#$MYSQL_CLUSTER_DIR#g;
383                 " /usr/share/mysql/mysqld.conf > "$MYSQL_CLUSTER_DIR/mysqld.conf"
384             chown root:root "$MYSQL_CLUSTER_DIR/mysqld.conf"
385             chmod 640 "$MYSQL_CLUSTER_DIR/mysqld.conf"
386         fi
387
388         if [ ! -e /var/lib/mysql/mysql.sock ] || [ -L /var/lib/mysql/mysql.sock ] && [ -z "$(readlink /var/lib/mysql/mysql.sock)" ]; then
389                 sock=${MYSQL_SOCKET#/var/lib/mysql/} # make it relative if possible
390             ln -s "$sock" /var/lib/mysql/mysql.sock
391         fi
392
393         cat > $MYSQL_DATA_DIR/mysql-init.sql <<-EOF
394                 CREATE DATABASE mysql;
395                 use mysql;
396                 $(sed -e "s,@ENGINE@,$BASE_TABLETYPE," /usr/share/mysql/init_db.sql)
397                 $(sed -e "s,\$hostname,$hostname,g" /usr/share/mysql/init_db-data.sql)
398                 "
399 EOF
400
401         ok=0
402         /usr/sbin/mysqld --bootstrap --skip-grant-tables \
403                 --datadir=$MYSQL_DATA_DIR --user=$MYSQL_USER < $MYSQL_DATA_DIR/mysql-init.sql && ok=1
404         [ -f $MYSQL_DATA_DIR/mysql/user.frm ] || ok=0
405         if [ "$ok" = 1 ]; then
406                 rm -f $MYSQL_DATA_DIR/mysql-init.sql
407             ok
408         cat << END_OF_MSG
409
410 PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL USERS!
411 This is done (after starting database; press enter when asked for password) with:
412
413 /usr/bin/mysqladmin -u mysql -S $MYSQL_SOCKET password 'password'
414 /usr/bin/mysqladmin -h $hostname -u mysql -S $MYSQL_SOCKET password 'password'
415 /usr/bin/mysqladmin -u mysql_logrotate -S $MYSQL_SOCKET password 'password'
416
417 NOTE: mysql_logrotate password should be placed to $MYSQL_CONFIG in
418 mysqladmin section. See the manual for more instructions.
419
420 If you want to use new help tables in MySQL 4.1.x then you'll need to import the help data:
421 /usr/bin/mysql -u mysql -p -S $MYSQL_SOCKET mysql < /usr/share/mysql/fill_help_tables.sql
422
423 END_OF_MSG
424       else
425             fail
426             cat << END_OF_MSG
427 Installation of grant tables FAILED!
428
429 Examine the logs in /var/log/mysql for more information.  You can
430 also try to start the mysqld daemon with:
431
432 /usr/sbin/mysqld --skip-grant &
433
434 You can use the command line tool /usr/bin/mysql to connect to the mysql
435 database and look at the grant tables:
436
437 shell> /usr/bin/mysql -u mysql mysql
438 mysql> show tables
439
440 Try 'mysqld --help' if you have problems with paths. Setting on
441 logging in /etc/mysqld.conf gives you a log in /var/log/mysql/log that
442 may be helpful. The latest information about MySQL is available on the
443 web at http://www.mysql.com/.
444
445 Please check PLD Linux ftp site for newer versions of this package.
446
447 Please consult the MySQL manual section: 'Problems running
448 mysql_install_db', and the manual section that describes problems on
449 your OS.  Another information source is the MySQL email archive.
450 Please check all of the above before mailing us!  And if you do mail
451 us, you MUST use the /usr/bin/mysqlbug script!
452
453 END_OF_MSG
454
455         exit 1
456         fi
457 }
458
459 #
460 # End of useful functions.
461 #
462
463 start() {
464         if [ ! -f $MYSQL_ERRLOG ]; then
465                 touch $MYSQL_ERRLOG
466         fi
467         chown mysql:mysql $MYSQL_ERRLOG
468         chmod 640 $MYSQL_ERRLOG
469
470         for mysqldir in $DB_CLUSTERS; do
471                 mysqlstatus "$mysqldir" start
472                 if [ "$MYSQL_STATUS" = "running" ]; then
473                         msg_already_running "MySQL $mysqldir"
474                 else
475                         mysqlstart "$mysqldir"
476                 fi
477         done
478         mysqlsubsys
479 }
480
481 stop() {
482         for mysqldir in $DB_CLUSTERS; do
483                 mysqlstatus "$mysqldir" stop
484                 if [ "$MYSQL_STATUS" = "not running" ]; then
485                         msg_not_running "MySQL $mysqldir"
486                 else
487                         mysqlstop "$mysqldir"
488                 fi
489         done
490         mysqlsubsys
491 }
492
493 RETVAL=0
494 case "$action" in
495   start)
496         start
497         ;;
498   stop)
499         stop
500         ;;
501   status)
502         for mysqldir in $DB_CLUSTERS; do
503                 mysqlstatus "$mysqldir"
504                 if [ "$MYSQL_STATUS" = "running" ]; then
505                         show "MySQL cluster %s, PID %s" "$mysqldir" "$MYSQL_PID"
506                         progress "$MYSQL_STATUS"
507                 else
508                         show "MySQL cluster %s" "$mysqldir"
509                         progress "$MYSQL_STATUS" "$CFAIL"
510                 fi
511                 echo
512         done
513         exit $?
514         ;;
515   restart|force-reload)
516         stop
517         start
518         ;;
519   init)
520         for mysqldir in $DB_CLUSTERS; do
521                 mysqlinit "$mysqldir"
522         done
523         exit $?
524         ;;
525   flush-logs)
526         for mysqldir in $DB_CLUSTERS; do
527             mysqlgetconfig "$mysqldir"
528                 # just if mysqld is really running
529                 if /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" ping >/dev/null 2>&1; then
530                         /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" flush-logs
531                 fi
532         done
533         ;;
534   *)
535         msg_usage "$0 {start|stop|init|restart|force-reload|status}"
536         exit 3
537 esac
538
539 exit $RETVAL
540
541 # vi: shiftwidth=4 tabstop=4
This page took 0.080284 seconds and 4 git commands to generate.