mysqld_safe.sh 9.4 KB
Newer Older
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1 2 3 4 5 6 7 8 9 10
#!/bin/sh
# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
# This file is public domain and comes with NO WARRANTY of any kind
#
# scripts to start the MySQL daemon and restart it if it dies unexpectedly
#
# This should be executed in the MySQL base directory if you are using a
# binary installation that has other paths than you are using.
#
# mysql.server works by first doing a cd to the base directory and from there
11
# executing mysqld_safe
bk@work.mysql.com's avatar
bk@work.mysql.com committed
12 13 14 15 16

trap '' 1 2 3 15			# we shouldn't let anyone kill us

defaults=
case "$1" in
17
    --no-defaults|--defaults-file=*|--defaults-extra-file=*)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
18 19 20 21 22
      defaults="$1"; shift
      ;;
esac

parse_arguments() {
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
  # We only need to pass arguments through to the server if we don't
  # handle them here.  So, we collect unrecognized options (passed on
  # the command line) into the args variable.
  pick_args=
  if test "$1" = PICK-ARGS-FROM-ARGV
  then
    pick_args=1
    shift
  fi

  for arg do
    case "$arg" in
      # these get passed explicitly to mysqld
      --basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--basedir=;;"` ;;
      --datadir=*) DATADIR=`echo "$arg" | sed -e "s;--datadir=;;"` ;;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
38
      --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--pid-file=;;"` ;;
39
      --user=*)    user=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; SET_USER=1 ;;
40

41 42
      # these two might have been set in a [mysqld_safe] section of my.cnf
      # they get passed via environment variables to mysqld_safe
43 44 45
      --socket=*)  MYSQL_UNIX_PORT=`echo "$arg" | sed -e "s;--socket=;;"` ;;
      --port=*)    MYSQL_TCP_PORT=`echo "$arg" | sed -e "s;--port=;;"` ;;

46
      # mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])!
47 48
      --ledir=*)   ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;;
      --err-log=*) err_log=`echo "$arg" | sed -e "s;--err-log=;;"` ;;
monty@donna.mysql.com's avatar
monty@donna.mysql.com committed
49
      # QQ The --open-files should be removed
50
      --open-files=*) open_files=`echo "$arg" | sed -e "s;--open-files=;;"` ;;
monty@donna.mysql.com's avatar
monty@donna.mysql.com committed
51
      --open-files-limit=*) open_files=`echo "$arg" | sed -e "s;--open-files-limit=;;"` ;;
52
      --core-file-size=*) core_file_size=`echo "$arg" | sed -e "s;--core_file_size=;;"` ;;
53
      --timezone=*) TZ=`echo "$arg" | sed -e "s;--timezone=;;"` ; export TZ; ;;
54
      --mysqld=*)   MYSQLD=`echo "$arg" | sed -e "s;--mysqld=;;"` ;;
monty@donna.mysql.fi's avatar
monty@donna.mysql.fi committed
55 56 57 58 59 60 61 62 63
      --mysqld-version=*)
	tmp=`echo "$arg" | sed -e "s;--mysqld-version=;;"`
	if test -n "$tmp"
	then
	  MYSQLD="mysqld-$tmp"
	else
	  MYSQLD="mysqld"
	fi
	;;
64 65 66 67 68 69 70 71
      *)
        if test -n "$pick_args"
        then
          # This sed command makes sure that any special chars are quoted,
          # so the arg gets passed exactly to the server.
          args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'`
        fi
        ;;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
72 73 74 75 76 77 78 79 80 81 82 83
    esac
  done
}

MY_PWD=`pwd`
# Check if we are starting this relative (for the binary release)
if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
 -x ./bin/mysqld
then
  MY_BASEDIR_VERSION=$MY_PWD		# Where bin, share and data are
  ledir=$MY_BASEDIR_VERSION/bin		# Where mysqld is
  DATADIR=$MY_BASEDIR_VERSION/data
monty@donna.mysql.fi's avatar
monty@donna.mysql.fi committed
84
  if test -z "$defaults"
85 86 87
  then
    defaults="--defaults-extra-file=$MY_BASEDIR_VERSION/data/my.cnf"
  fi
bk@work.mysql.com's avatar
bk@work.mysql.com committed
88 89 90 91 92 93 94 95 96 97 98 99 100
# Check if this is a 'moved install directory'
elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
 -x ./libexec/mysqld
then
  MY_BASEDIR_VERSION=$MY_PWD		# Where libexec, share and var are
  ledir=$MY_BASEDIR_VERSION/libexec	# Where mysqld is
  DATADIR=$MY_BASEDIR_VERSION/var
else
  MY_BASEDIR_VERSION=@prefix@
  DATADIR=@localstatedir@
  ledir=@libexecdir@
fi

101 102
MYSQL_UNIX_PORT=${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}
MYSQL_TCP_PORT=${MYSQL_TCP_PORT:-@MYSQL_TCP_PORT@}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
103
user=@MYSQLD_USER@
104 105 106 107 108 109 110 111

# Use the mysqld-max binary by default if the user doesn't specify a binary
if test -x $ledir/mysqld-max
then
  MYSQLD=mysqld-max
else
  MYSQLD=mysqld
fi
bk@work.mysql.com's avatar
bk@work.mysql.com committed
112

113 114 115
# these rely on $DATADIR by default, so we'll set them later on
pid_file=
err_log=
116
SET_USER=0
117

118
# Get first arguments from the my.cnf file, groups [mysqld] and [mysqld_safe]
bk@work.mysql.com's avatar
bk@work.mysql.com committed
119
# and then merge with the command line arguments
120 121
if test -x ./bin/my_print_defaults
then
bk@work.mysql.com's avatar
bk@work.mysql.com committed
122
  print_defaults="./bin/my_print_defaults"
123 124
elif test -x @bindir@/my_print_defaults
then
bk@work.mysql.com's avatar
bk@work.mysql.com committed
125
  print_defaults="@bindir@/my_print_defaults"
126 127
elif test -x @bindir@/mysql_print_defaults
then
bk@work.mysql.com's avatar
bk@work.mysql.com committed
128 129 130 131
  print_defaults="@bindir@/mysql_print_defaults"
else
  print_defaults="my_print_defaults"
fi
132 133

args=
134
parse_arguments `$print_defaults $defaults mysqld server mysqld_safe safe_mysqld`
135
parse_arguments PICK-ARGS-FROM-ARGV "$@"
bk@work.mysql.com's avatar
bk@work.mysql.com committed
136

137
if test ! -x $ledir/$MYSQLD
bk@work.mysql.com's avatar
bk@work.mysql.com committed
138
then
139
  echo "The file $ledir/$MYSQLD doesn't exist or is not executable"
bk@work.mysql.com's avatar
bk@work.mysql.com committed
140 141
  echo "Please do a cd to the mysql installation directory and restart"
  echo "this script from there as follows:"
142
  echo "./bin/mysqld_safe".
143
  exit 1
bk@work.mysql.com's avatar
bk@work.mysql.com committed
144 145
fi

146 147 148 149 150 151 152 153 154
if test -z "$pid_file"
then
  pid_file=$DATADIR/`@HOSTNAME@`.pid
else
  case "$pid_file" in
    /* ) ;;
    * )  pid_file="$DATADIR/$pid_file" ;;
  esac
fi
155 156 157 158 159
test -z "$err_log"  && err_log=$DATADIR/`@HOSTNAME@`.err

export MYSQL_UNIX_PORT
export MYSQL_TCP_PORT

bk@work.mysql.com's avatar
bk@work.mysql.com committed
160

161
NOHUP_NICENESS="nohup"
162 163 164 165 166 167 168

# Using nice with no args to get the niceness level is GNU-specific.
# This check could be extended for other operating systems (e.g.,
# BSD could use "nohup sh -c 'ps -o nice -p $$' | tail -1").
# But, it also seems that GNU nohup is the only one which messes
# with the priority, so this is okay.
if nohup nice > /dev/null 2>&1
169
then
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
    normal_niceness=`nice`
    nohup_niceness=`nohup nice`

    numeric_nice_values=1
    for val in $normal_niceness $nohup_niceness
    do
        case "$val" in
            -[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | \
             [0-9] |  [0-9][0-9] |  [0-9][0-9][0-9] )
                ;;
            * )
                numeric_nice_values=0 ;;
        esac
    done

    if test $numeric_nice_values -eq 1
    then
        nice_value_diff=`expr $nohup_niceness - $normal_niceness`
        if test $? -eq 0 && test $nice_value_diff -gt 0 && \
            nice --$nice_value_diff echo testing > /dev/null 2>&1
        then
            # nohup increases the priority (bad), and we are permitted
            # to lower the priority
            NOHUP_NICENESS="nice --$nice_value_diff nohup"
        fi
    fi
else
    if nohup echo testing > /dev/null 2>&1
    then
        :
    else
        # nohup doesn't work on this system
        NOHUP_NICENESS=""
    fi
bk@work.mysql.com's avatar
bk@work.mysql.com committed
204 205
fi

206
USER_OPTION=""
207 208
if test -w /
then
209 210 211 212
  if test "$user" != "root" -o $SET_USER = 1
  then
    USER_OPTION="--user=$user"
  fi
213 214
  # If we are root, change the err log to the right user.
  touch $err_log; chown $user $err_log
215 216 217 218 219 220 221 222
  if test -n "$open_files"
  then
    ulimit -n $open_files
  fi
  if test -n "$core_file_size"
  then
    ulimit -c $core_file_size
  fi
223
fi
bk@work.mysql.com's avatar
bk@work.mysql.com committed
224 225 226 227 228 229 230 231 232 233 234 235 236

#
# If there exists an old pid file, check if the daemon is already running
# Note: The switches to 'ps' may depend on your operating system
if test -f $pid_file
then
  PID=`cat $pid_file`
  if @CHECK_PID@
  then
    if @FIND_PROC@
    then    # The pid contains a mysqld process
      echo "A mysqld process already exists"
      echo "A mysqld process already exists at " `date` >> $err_log
237
      exit 1
bk@work.mysql.com's avatar
bk@work.mysql.com committed
238 239 240 241 242 243 244 245 246
    fi
  fi
  rm -f $pid_file
  if test -f $pid_file
  then
    echo "Fatal error: Can't remove the pid file: $pid_file"
    echo "Fatal error: Can't remove the pid file: $pid_file at " `date` >> $err_log
    echo "Please remove it manually and start $0 again"
    echo "mysqld daemon not started"
247
    exit 1
bk@work.mysql.com's avatar
bk@work.mysql.com committed
248 249 250 251 252 253 254 255
  fi
fi

#
# Uncomment the following lines if you want all tables to be automaticly
# checked and repaired at start
#
# echo "Checking tables in $DATADIR"
256 257
# $MY_BASEDIR_VERSION/bin/myisamchk --silent --force --fast --medium-check -O key_buffer=64M -O sort_buffer=64M $DATADIR/*/*.MYI
# $MY_BASEDIR_VERSION/bin/isamchk --silent --force -O sort_buffer=64M $DATADIR/*/*.ISM
bk@work.mysql.com's avatar
bk@work.mysql.com committed
258

259
echo "Starting $MYSQLD daemon with databases from $DATADIR"
bk@work.mysql.com's avatar
bk@work.mysql.com committed
260 261 262 263 264 265 266 267 268 269 270

# Does this work on all systems?
#if type ulimit | grep "shell builtin" > /dev/null
#then
#  ulimit -n 256 > /dev/null 2>&1		# Fix for BSD and FreeBSD systems
#fi

echo "`date +'%y%m%d %H:%M:%S  mysqld started'`" >> $err_log
while true
do
  rm -f $MYSQL_UNIX_PORT $pid_file	# Some extra safety
271
  if test -z "$args"
bk@work.mysql.com's avatar
bk@work.mysql.com committed
272
  then
273
    $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1
bk@work.mysql.com's avatar
bk@work.mysql.com committed
274
  else
275
    eval "$NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ $args >> $err_log 2>&1"
bk@work.mysql.com's avatar
bk@work.mysql.com committed
276 277 278
  fi
  if test ! -f $pid_file		# This is removed if normal shutdown
  then
279
    break
bk@work.mysql.com's avatar
bk@work.mysql.com committed
280
  fi
281

bk@work.mysql.com's avatar
bk@work.mysql.com committed
282 283 284 285 286 287 288
  if @IS_LINUX@
  then
    # Test if one process was hanging.
    # This is only a fix for Linux (running as base 3 mysqld processes)
    # but should work for the rest of the servers.
    # The only thing is ps x => redhat 5 gives warnings when using ps -x.
    # kill -9 is used or the process won't react on the kill.
289
    numofproces=`ps xa | grep -v "grep" | grep -c $ledir/$MYSQLD`
bk@work.mysql.com's avatar
bk@work.mysql.com committed
290 291 292 293
    echo -e "\nNumber of processes running now: $numofproces" | tee -a $err_log
    I=1
    while test "$I" -le "$numofproces"
    do 
294
      PROC=`ps xa | grep $ledir/$MYSQLD | grep -v "grep" | sed -n '$p'` 
bk@work.mysql.com's avatar
bk@work.mysql.com committed
295 296 297 298 299 300 301
	for T in $PROC
	do
	  break
	done
	#    echo "TEST $I - $T **"
	if kill -9 $T
	then
302
	  echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log
bk@work.mysql.com's avatar
bk@work.mysql.com committed
303 304 305 306 307 308
	else 
	  break
	fi
	I=`expr $I + 1`
    done
  fi
309

bk@work.mysql.com's avatar
bk@work.mysql.com committed
310 311 312
  echo "`date +'%y%m%d %H:%M:%S  mysqld restarted'`" | tee -a $err_log
done

313
echo "`date +'%y%m%d %H:%M:%S  mysqld ended'`" | tee -a $err_log
314
echo "" | tee -a $err_log