1#!/bin/sh
2# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
3# This file is public domain and comes with NO WARRANTY of any kind
4
5# MySQL (Percona Server) daemon start/stop script.
6
7# Usually this is put in /etc/init.d (at least on machines SYSV R4 based
8# systems) and linked to /etc/rc3.d/S99mysql and /etc/rc0.d/K01mysql.
9# When this is done the mysql server will be started when the machine is
10# started and shut down when the systems goes down.
11
12# Comments to support chkconfig on RedHat Linux
13# chkconfig: 2345 64 36
14# description: A very fast and reliable SQL database engine.
15
16# Comments to support LSB init script conventions
17### BEGIN INIT INFO
18# Provides: mysql
19# Required-Start: $local_fs $network $remote_fs
20# Should-Start: ypbind nscd ldap ntpd xntpd
21# Required-Stop: $local_fs $network $remote_fs
22# Default-Start:  2 3 4 5
23# Default-Stop: 0 1 6
24# Short-Description: start and stop MySQL (Percona Server)
25# Description: Percona-Server is a SQL database engine with focus on high performance.
26### END INIT INFO
27
28# If you install MySQL on some other places than @prefix@, then you
29# have to do one of the following things for this script to work:
30#
31# - Run this script from within the MySQL installation directory
32# - Create a /etc/my.cnf file with the following information:
33#   [mysqld]
34#   basedir=<path-to-mysql-installation-directory>
35# - Add the above to any other configuration file (for example ~/.my.ini)
36#   and copy my_print_defaults to /usr/bin
37# - Add the path to the mysql-installation-directory to the basedir variable
38#   below.
39#
40# If you want to affect other MySQL variables, you should make your changes
41# in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files.
42
43# If you change base dir, you must also change datadir. These may get
44# overwritten by settings in the MySQL configuration files.
45
46basedir=
47datadir=
48
49# Default value, in seconds, afterwhich the script should timeout waiting
50# for server start.
51# Value here is overriden by value in my.cnf.
52# 0 means don't wait at all
53# Negative numbers mean to wait indefinitely
54service_startup_timeout=900
55
56# Lock directory for RedHat / SuSE.
57lockdir='/var/lock/subsys'
58lock_file_path="$lockdir/mysql"
59
60# The following variables are only set for letting mysql.server find things.
61
62# Set some defaults
63mysqld_pid_file_path=
64if test -z "$basedir"
65then
66  basedir=@prefix@
67  bindir=@bindir@
68  if test -z "$datadir"
69  then
70    datadir=@localstatedir@
71  fi
72  sbindir=@sbindir@
73  libexecdir=@libexecdir@
74else
75  bindir="$basedir/bin"
76  if test -z "$datadir"
77  then
78    datadir="$basedir/data"
79  fi
80  sbindir="$basedir/sbin"
81  libexecdir="$basedir/libexec"
82fi
83
84# datadir_set is used to determine if datadir was set (and so should be
85# *not* set inside of the --basedir= handler.)
86datadir_set=
87
88#
89# Use LSB init script functions for printing messages, if possible
90#
91lsb_functions="/lib/lsb/init-functions"
92if test -f $lsb_functions ; then
93  . $lsb_functions
94else
95  log_success_msg()
96  {
97    echo " SUCCESS! $@"
98  }
99  log_failure_msg()
100  {
101    echo " ERROR! $@"
102  }
103fi
104
105PATH="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin"
106export PATH
107
108mode=$1    # start or stop
109
110[ $# -ge 1 ] && shift
111
112
113other_args="$*"   # uncommon, but needed when called from an RPM upgrade action
114           # Expected: "--skip-networking --skip-grant-tables"
115           # They are not checked here, intentionally, as it is the resposibility
116           # of the "spec" file author to give correct arguments only.
117
118case `echo "testing\c"`,`echo -n testing` in
119    *c*,-n*) echo_n=   echo_c=     ;;
120    *c*,*)   echo_n=-n echo_c=     ;;
121    *)       echo_n=   echo_c='\c' ;;
122esac
123
124parse_server_arguments() {
125  for arg do
126    case "$arg" in
127      --basedir=*)  basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`
128                    bindir="$basedir/bin"
129		    if test -z "$datadir_set"; then
130		      datadir="$basedir/data"
131		    fi
132		    sbindir="$basedir/sbin"
133		    libexecdir="$basedir/libexec"
134        ;;
135      --datadir=*)  datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`
136		    datadir_set=1
137	;;
138      --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
139      --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
140    esac
141  done
142}
143
144wait_for_pid () {
145  verb="$1"           # created | removed
146  pid="$2"            # process ID of the program operating on the pid-file
147  pid_file_path="$3" # path to the PID file.
148
149  i=0
150  avoid_race_condition="by checking again"
151
152  while test $i -ne $service_startup_timeout ; do
153
154    case "$verb" in
155      'created')
156        # wait for a PID-file to pop into existence.
157        test -s "$pid_file_path" && i='' && break
158        ;;
159      'removed')
160        # wait for this PID-file to disappear
161        test ! -s "$pid_file_path" && i='' && break
162        ;;
163      *)
164        echo "wait_for_pid () usage: wait_for_pid created|removed pid pid_file_path"
165        exit 1
166        ;;
167    esac
168
169    # if server isn't running, then pid-file will never be updated
170    if test -n "$pid"; then
171      if kill -0 "$pid" 2>/dev/null; then
172        :  # the server still runs
173      else
174        # The server may have exited between the last pid-file check and now.
175        if test -n "$avoid_race_condition"; then
176          avoid_race_condition=""
177          continue  # Check again.
178        fi
179
180        # there's nothing that will affect the file.
181        log_failure_msg "The server quit without updating PID file ($pid_file_path)."
182        return 1  # not waiting any more.
183      fi
184    fi
185
186    echo $echo_n ".$echo_c"
187    i=`expr $i + 1`
188    sleep 1
189
190  done
191
192  if test -z "$i" ; then
193    log_success_msg
194    return 0
195  else
196    log_failure_msg
197    return 1
198  fi
199}
200
201# Get arguments from the my.cnf file,
202# the only group, which is read from now on is [mysqld]
203if test -x "$bindir/my_print_defaults";  then
204  print_defaults="$bindir/my_print_defaults"
205else
206  # Try to find basedir in /etc/my.cnf
207  conf=/etc/my.cnf
208  print_defaults=
209  if test -r $conf
210  then
211    subpat='^[^=]*basedir[^=]*=\(.*\)$'
212    dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf`
213    for d in $dirs
214    do
215      d=`echo $d | sed -e 's/[ 	]//g'`
216      if test -x "$d/bin/my_print_defaults"
217      then
218        print_defaults="$d/bin/my_print_defaults"
219        break
220      fi
221    done
222  fi
223
224  # Hope it's in the PATH ... but I doubt it
225  test -z "$print_defaults" && print_defaults="my_print_defaults"
226fi
227
228#
229# Read defaults file from 'basedir'.   If there is no defaults file there
230# check if it's in the old (depricated) place (datadir) and read it from there
231#
232
233extra_args=""
234if test -r "$basedir/my.cnf"
235then
236  extra_args="-e $basedir/my.cnf"
237fi
238
239parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
240
241#
242# Set pid file if not given
243#
244if test -z "$mysqld_pid_file_path"
245then
246  mysqld_pid_file_path=$datadir/`@HOSTNAME@`.pid
247else
248  case "$mysqld_pid_file_path" in
249    /* ) ;;
250    * )  mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;;
251  esac
252fi
253
254case "$mode" in
255  'start')
256    # Start daemon
257
258    # Safeguard (relative paths, core dumps..)
259    cd $basedir
260
261    echo $echo_n "Starting MySQL (Percona Server)"
262    if test -x $bindir/mysqld_safe
263    then
264      # Give extra arguments to mysqld with the my.cnf file. This script
265      # may be overwritten at next upgrade.
266      $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &
267      wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
268
269      # Make lock for RedHat / SuSE
270      if test -w "$lockdir"
271      then
272        touch "$lock_file_path"
273      fi
274
275      exit $return_value
276    else
277      log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)"
278    fi
279    ;;
280
281  'stop')
282    # Stop daemon. We use a signal here to avoid having to know the
283    # root password.
284
285    if test -s "$mysqld_pid_file_path"
286    then
287      # signal mysqld_safe that it needs to stop
288      touch "$mysqld_pid_file_path.shutdown"
289
290      mysqld_pid=`cat "$mysqld_pid_file_path"`
291
292      if (kill -0 $mysqld_pid 2>/dev/null)
293      then
294        echo $echo_n "Shutting down MySQL (Percona Server)"
295        kill $mysqld_pid
296        # mysqld should remove the pid file when it exits, so wait for it.
297        wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$?
298      else
299        log_failure_msg "MySQL (Percona Server) server process #$mysqld_pid is not running!"
300        rm "$mysqld_pid_file_path"
301      fi
302
303      # Delete lock for RedHat / SuSE
304      if test -f "$lock_file_path"
305      then
306        rm -f "$lock_file_path"
307      fi
308      exit $return_value
309    else
310      log_failure_msg "MySQL (Percona Server) PID file could not be found!"
311    fi
312    ;;
313
314  'restart')
315    # Stop the service and regardless of whether it was
316    # running or not, start it again.
317    if $0 stop  $other_args; then
318      $0 start $other_args
319    else
320      log_failure_msg "Failed to stop running server, so refusing to try to start."
321      exit 1
322    fi
323    ;;
324
325  'reload'|'force-reload')
326    if test -s "$mysqld_pid_file_path" ; then
327      read mysqld_pid <  "$mysqld_pid_file_path"
328      kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL (Percona Server)"
329      touch "$mysqld_pid_file_path"
330    else
331      log_failure_msg "MySQL (Percona Server) PID file could not be found!"
332      exit 1
333    fi
334    ;;
335  'status')
336    # First, check to see if pid file exists
337    if test -s "$mysqld_pid_file_path" ; then
338      read mysqld_pid < "$mysqld_pid_file_path"
339      if kill -0 $mysqld_pid 2>/dev/null ; then
340        log_success_msg "MySQL (Percona Server) running ($mysqld_pid)"
341        exit 0
342      else
343        log_failure_msg "MySQL (Percona Server) is not running, but PID file exists"
344        exit 1
345      fi
346    else
347      # Try to find appropriate mysqld process
348      mysqld_pid=`@PIDOF@ $libexecdir/mysqld`
349
350      # test if multiple pids exist
351      pid_count=`echo $mysqld_pid | wc -w`
352      if test $pid_count -gt 1 ; then
353        log_failure_msg "Multiple MySQL running but PID file could not be found ($mysqld_pid)"
354        exit 5
355      elif test -z $mysqld_pid ; then
356        if test -f "$lock_file_path" ; then
357          log_failure_msg "MySQL (Percona Server) is not running, but lock file ($lock_file_path) exists"
358          exit 2
359        fi
360        log_failure_msg "MySQL (Percona Server) is not running"
361        exit 3
362      else
363        log_failure_msg "MySQL (Percona Server) is running but PID file could not be found"
364        exit 4
365      fi
366    fi
367    ;;
368    *)
369      # usage
370      basename=`basename "$0"`
371      echo "Usage: $basename  {start|stop|restart|reload|force-reload|status}  [ MySQL (Percona Server) options ]"
372      exit 1
373    ;;
374esac
375
376exit 0
377