mysqld_safe.sh 9.47 KB
Newer Older
unknown's avatar
unknown 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
unknown's avatar
unknown committed
11
# executing mysqld_safe
unknown's avatar
unknown committed
12 13 14

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

15 16
umask 007

unknown's avatar
unknown committed
17 18
defaults=
case "$1" in
unknown's avatar
unknown committed
19
    --no-defaults|--defaults-file=*|--defaults-extra-file=*)
unknown's avatar
unknown committed
20 21 22 23 24
      defaults="$1"; shift
      ;;
esac

parse_arguments() {
unknown's avatar
unknown committed
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
  # 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=;;"` ;;
unknown's avatar
unknown committed
40
      --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--pid-file=;;"` ;;
41
      --user=*)    user=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; SET_USER=1 ;;
unknown's avatar
unknown committed
42

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

unknown's avatar
unknown committed
48
      # mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])!
unknown's avatar
unknown committed
49 50
      --ledir=*)   ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;;
      --err-log=*) err_log=`echo "$arg" | sed -e "s;--err-log=;;"` ;;
unknown's avatar
unknown committed
51
      # QQ The --open-files should be removed
52
      --open-files=*) open_files=`echo "$arg" | sed -e "s;--open-files=;;"` ;;
unknown's avatar
unknown committed
53
      --open-files-limit=*) open_files=`echo "$arg" | sed -e "s;--open-files-limit=;;"` ;;
unknown's avatar
unknown committed
54
      --core-file-size=*) core_file_size=`echo "$arg" | sed -e "s;--core_file_size=;;"` ;;
55
      --timezone=*) TZ=`echo "$arg" | sed -e "s;--timezone=;;"` ; export TZ; ;;
unknown's avatar
unknown committed
56
      --mysqld=*)   MYSQLD=`echo "$arg" | sed -e "s;--mysqld=;;"` ;;
unknown's avatar
unknown committed
57 58 59 60 61 62 63 64 65
      --mysqld-version=*)
	tmp=`echo "$arg" | sed -e "s;--mysqld-version=;;"`
	if test -n "$tmp"
	then
	  MYSQLD="mysqld-$tmp"
	else
	  MYSQLD="mysqld"
	fi
	;;
unknown's avatar
unknown committed
66 67 68 69 70 71 72 73
      *)
        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
        ;;
unknown's avatar
unknown committed
74 75 76 77 78 79 80 81 82 83 84 85
    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
unknown's avatar
unknown committed
86
  if test -z "$defaults"
unknown's avatar
unknown committed
87 88 89
  then
    defaults="--defaults-extra-file=$MY_BASEDIR_VERSION/data/my.cnf"
  fi
unknown's avatar
unknown committed
90 91 92 93 94 95 96 97 98 99 100 101 102
# 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

103 104
MYSQL_UNIX_PORT=${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}
MYSQL_TCP_PORT=${MYSQL_TCP_PORT:-@MYSQL_TCP_PORT@}
unknown's avatar
unknown committed
105
user=@MYSQLD_USER@
106 107 108 109 110 111 112 113

# 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
unknown's avatar
unknown committed
114

unknown's avatar
unknown committed
115 116 117
# these rely on $DATADIR by default, so we'll set them later on
pid_file=
err_log=
118
SET_USER=0
unknown's avatar
unknown committed
119

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

args=
unknown's avatar
unknown committed
136
parse_arguments `$print_defaults $defaults mysqld server mysqld_safe safe_mysqld`
unknown's avatar
unknown committed
137
parse_arguments PICK-ARGS-FROM-ARGV "$@"
unknown's avatar
unknown committed
138

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

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

export MYSQL_UNIX_PORT
export MYSQL_TCP_PORT

unknown's avatar
unknown committed
162

unknown's avatar
unknown committed
163
NOHUP_NICENESS="nohup"
164 165 166 167 168 169 170

# 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
unknown's avatar
unknown committed
171
then
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 204 205
    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
unknown's avatar
unknown committed
206 207
fi

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

#
# 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
unknown's avatar
unknown committed
240
      exit 1
unknown's avatar
unknown committed
241 242 243 244 245 246 247 248 249
    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"
unknown's avatar
unknown committed
250
    exit 1
unknown's avatar
unknown committed
251 252 253 254 255 256 257 258
  fi
fi

#
# Uncomment the following lines if you want all tables to be automaticly
# checked and repaired at start
#
# echo "Checking tables in $DATADIR"
unknown's avatar
unknown committed
259 260
# $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
unknown's avatar
unknown committed
261

unknown's avatar
unknown committed
262
echo "Starting $MYSQLD daemon with databases from $DATADIR"
unknown's avatar
unknown committed
263 264 265 266 267 268 269 270 271 272 273

# 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
unknown's avatar
unknown committed
274
  if test -z "$args"
unknown's avatar
unknown committed
275
  then
unknown's avatar
unknown committed
276
    $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1
unknown's avatar
unknown committed
277
  else
unknown's avatar
unknown committed
278
    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"
unknown's avatar
unknown committed
279 280 281
  fi
  if test ! -f $pid_file		# This is removed if normal shutdown
  then
unknown's avatar
unknown committed
282
    break
unknown's avatar
unknown committed
283
  fi
unknown's avatar
unknown committed
284

unknown's avatar
unknown committed
285 286 287 288 289 290 291
  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.
unknown's avatar
unknown committed
292
    numofproces=`ps xa | grep -v "grep" | grep -c $ledir/$MYSQLD`
unknown's avatar
unknown committed
293 294 295 296
    echo -e "\nNumber of processes running now: $numofproces" | tee -a $err_log
    I=1
    while test "$I" -le "$numofproces"
    do 
unknown's avatar
unknown committed
297
      PROC=`ps xa | grep $ledir/$MYSQLD | grep -v "grep" | sed -n '$p'` 
unknown's avatar
unknown committed
298 299 300 301 302 303 304
	for T in $PROC
	do
	  break
	done
	#    echo "TEST $I - $T **"
	if kill -9 $T
	then
unknown's avatar
unknown committed
305
	  echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log
unknown's avatar
unknown committed
306 307 308 309 310 311
	else 
	  break
	fi
	I=`expr $I + 1`
    done
  fi
unknown's avatar
unknown committed
312

313
  echo "`date +'%y%m%d %H:%M:%S'`  mysqld restarted" | tee -a $err_log
unknown's avatar
unknown committed
314 315
done

unknown's avatar
unknown committed
316
echo "`date +'%y%m%d %H:%M:%S'`  mysqld ended" | tee -a $err_log
317
echo "" | tee -a $err_log