529 lines
16 KiB
Bash
529 lines
16 KiB
Bash
#!/bin/bash
|
|
# Copyright (c) 1995-2010 SuSE Linux AG Nuernberg, Germany.
|
|
#
|
|
# Author: Lenz Grimmer
|
|
# Maintainer: Michal Hrusecky <mhrusecky@suse.cz>
|
|
#
|
|
# mysqld_multi extension added by Richard Bos, 2008
|
|
#
|
|
# /etc/init.d/mysql
|
|
#
|
|
# and its symbolic link
|
|
#
|
|
# /usr/sbin/rcmysql
|
|
#
|
|
### BEGIN INIT INFO
|
|
# Provides: mysql
|
|
# Required-Start: $network $remote_fs
|
|
# Required-Stop: $network $remote_fs
|
|
# Default-Start: 2 3 5
|
|
# Default-Stop:
|
|
# Short-Description: Start the MySQL database server
|
|
# Description: Start the MySQL database server
|
|
### END INIT INFO
|
|
|
|
# Shell functions sourced from /etc/rc.status:
|
|
# rc_check check and set local and overall rc status
|
|
# rc_status check and set local and overall rc status
|
|
# rc_status -v ditto but be verbose in local rc status
|
|
# rc_status -v -r ditto and clear the local rc status
|
|
# rc_failed set local and overall rc status to failed
|
|
# rc_failed <num> set local and overall rc status to <num>
|
|
# rc_reset clear local rc status (overall remains)
|
|
# rc_exit exit appropriate to overall rc status
|
|
. /etc/rc.status
|
|
|
|
# First reset status of this service
|
|
rc_reset
|
|
|
|
# Return values acc. to LSB for all commands but status:
|
|
# 0 - success
|
|
# 1 - generic or unspecified error
|
|
# 2 - invalid or excess argument(s)
|
|
# 3 - unimplemented feature (e.g. "reload")
|
|
# 4 - insufficient privilege
|
|
# 5 - program is not installed
|
|
# 6 - program is not configured
|
|
# 7 - program is not running
|
|
#
|
|
# Note that starting an already running service, stopping
|
|
# or restarting a not-running service as well as the restart
|
|
# with force-reload (in case signalling is not supported) are
|
|
# considered a success.
|
|
|
|
# Check for the location of initscript
|
|
if [ "`echo "$0" | grep "^\."`" ] || [ "`echo "$0" | grep "^[^/].*/"`" ]; then
|
|
MYSELF="`pwd`/$0"
|
|
else
|
|
MYSELF="$0"
|
|
fi
|
|
|
|
parse_arguments() {
|
|
for arg do
|
|
case "$arg" in
|
|
--basedir=*) basedir="`echo "$arg" | sed -e 's/^[^=]*=//'`" ;;
|
|
--datadir=*) datadir="`echo "$arg" | sed -e 's/^[^=]*=//'`" ;;
|
|
--pid-file=*) pid_file="`echo "$arg" | sed -e 's/^[^=]*=//'`" ;;
|
|
--socket=*) socket="`echo "$arg" | sed -e 's/^[^=]*=//'`" ;;
|
|
--log-error=*) log_error="`echo "$arg" | sed -e 's/^[^=]*=//'`" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
wait_for_socket()
|
|
{
|
|
local i
|
|
for((i=0; i<150; i++)); do
|
|
sleep 0.2
|
|
test -S $1 && i='' && break
|
|
done
|
|
test -z "$i" || return 1
|
|
return 0
|
|
}
|
|
|
|
# Don't run killproc -TERM, as it could send a SIGKILL as well, possibly
|
|
# resulting in database corruption. Run kill -TERM manually instead, wait
|
|
# approximately 300 seconds and fail if mysql doesn't respond. This will at
|
|
# least prevent the SIGKILL when doing 'rcmysql stop' manually. During system
|
|
# shutdown, we are out of luck...
|
|
# See https://bugzilla.novell.com/show_bug.cgi?id=223209
|
|
kill_mysql ()
|
|
{
|
|
local pid exe
|
|
test -e "$pid_file" || return 7 # not running
|
|
pid=`cat "$pid_file"` || return 4 # insufficient privileges
|
|
if ! test -e /proc/version; then
|
|
mount -n -t proc proc /proc
|
|
test -e /proc/version || return 100
|
|
fi
|
|
test -L "/proc/$pid/exe" || return 7
|
|
exe=`readlink "/proc/$pid/exe"` || return 4
|
|
test "`echo "$exe" | grep "^$MYSQLD"`" || return 7
|
|
kill -STOP "$pid"
|
|
kill -TERM "$pid" || return 4 # suboptimal
|
|
kill -CONT "$pid"
|
|
for i in `seq 3000`; do
|
|
# mysqld removes its pid file
|
|
test -e "$pid_file" || return 0
|
|
LC_ALL=C sleep 0.1
|
|
done
|
|
test -e "$pid_file" || return 0
|
|
return 1
|
|
}
|
|
|
|
# Helper function which can end with any status
|
|
set_return_value() {
|
|
return $1
|
|
}
|
|
|
|
# Checks for obsolete database
|
|
check_obsolete() {
|
|
# check for ISAM tables
|
|
tables="`find "$datadir" -name '*.ISM' 2> /dev/null | sed "s@$datadir/*@@; s@.ISM@@; s@/@.@;"`"
|
|
if test "$tables" ; then
|
|
echo
|
|
echo "Some tables still use ISAM format, which is NO LONGER SUPPORTED"
|
|
echo "since mysql 5.0. To use these tables, you would need to open them"
|
|
echo "from an older mysql server and convert to something better (eg. MyISAM)."
|
|
echo
|
|
echo "Tables using ISAM are: "
|
|
echo " $tables "
|
|
echo
|
|
fi
|
|
# check for bdb tables
|
|
tables="`find "$datadir" -name '*.db' 2> /dev/null | sed "s@$datadir/*@@; s@.db@@; s@/@.@;"`"
|
|
if test -n "$tables" ; then
|
|
echo
|
|
echo "Some tables still use BerkeleyDB format, which is NO LONGER SUPPORTED"
|
|
echo "since mysql 5.1. To use these tables, you would need to open them"
|
|
echo "from an older mysql server and convert to something better (eg. MyISAM)."
|
|
echo
|
|
echo "Tables using BerkeleyDB are: "
|
|
echo " $tables "
|
|
echo
|
|
fi
|
|
}
|
|
|
|
# Check if we want to run multiple instances.
|
|
[[ "`cat /etc/my.cnf | sed -n 's|^[[:blank:]]*\[mysqld[0-9]\+\]|yes|p'`" ]] && MYSQLD_MULTI=yes
|
|
|
|
# This was old way how to specify this, left for backward compatibility.
|
|
[[ -f /etc/sysconfig/mysql ]] && . /etc/sysconfig/mysql
|
|
|
|
if [[ "$MYSQLD_MULTI" == "yes" ]]; then
|
|
|
|
[[ -x /usr/bin/mysqld_multi ]] || {
|
|
echo -n "MySQL: /usr/bin/mysqld_multi not found"
|
|
rc_failed 5; rc_status -v; rc_exit;
|
|
}
|
|
|
|
case "$1" in
|
|
start)
|
|
|
|
# FIXME:
|
|
# We assume a fresh install if the directory $datadir/mysql
|
|
# does not exist and create the privilege database
|
|
# if ! test -d $datadir/mysql; then
|
|
# echo -n "Creating MySQL privilege database... "
|
|
# mysql_install_db --user=$mysql_daemon_user --datadir=$datadir || {
|
|
# rc_failed; rc_status -v; rc_exit
|
|
# }
|
|
# fi
|
|
echo -n "Starting service multi MySQL "
|
|
mysqld_multi start
|
|
|
|
# Remember status and be verbose
|
|
rc_status -v
|
|
;;
|
|
|
|
stop)
|
|
echo -n "Shutting down service multi MySQL "
|
|
mysqld_multi stop
|
|
|
|
# Remember status and be verbose
|
|
rc_status -v
|
|
;;
|
|
|
|
try-restart)
|
|
## Stop the service and if this succeeds (i.e. the
|
|
## service was running before), start it again.
|
|
## Note: try-restart is not (yet) part of LSB (as of 0.7.5)
|
|
"$MYSELF" status >/dev/null && "$MYSELF" restart
|
|
|
|
# Remember status and be quiet
|
|
rc_status
|
|
;;
|
|
|
|
restart|force-reload)
|
|
echo "Restarting service multi MySQL "
|
|
"$MYSELF" stop
|
|
"$MYSELF" start
|
|
|
|
rc_status
|
|
;;
|
|
|
|
reload)
|
|
echo -n "Reloading service multi MySQL "
|
|
mysqld_multi reload
|
|
rc_status -v
|
|
;;
|
|
|
|
status)
|
|
STATUS=$(mysqld_multi report)
|
|
echo -n "$STATUS"
|
|
# Set the status for rc_status
|
|
echo "$STATUS" | grep -q "is running"
|
|
rc_status -v
|
|
;;
|
|
|
|
*)
|
|
echo "Usage: $MYSELF {start|stop|status|reload|restart|try-restart|force-reload}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
else
|
|
# Test, if mysqld or mysql-max actually exist
|
|
unset MYSQLD
|
|
|
|
# use mysqld-debug only if explicitly requested (TODO: sysconfig variable?)
|
|
if test "$MYSQLD_DEBUG" = yes -a -x /usr/sbin/mysqld-debug
|
|
then
|
|
MYSQLD=/usr/sbin/mysqld-debug
|
|
elif test -x /usr/sbin/mysqld-max
|
|
then
|
|
MYSQLD=/usr/sbin/mysqld-max
|
|
elif test -x /usr/sbin/mysqld
|
|
then
|
|
MYSQLD=/usr/sbin/mysqld
|
|
fi
|
|
test "$MYSQLD" || {
|
|
echo -n "Nor /usr/sbin/mysqld nor /usr/sbin/mysqld-max exists";
|
|
rc_failed 5; rc_status -v; rc_exit;
|
|
}
|
|
|
|
|
|
# The following section has been taken from
|
|
# the original MySQL init script
|
|
# Note: If you want to change these variables, you'll make your life easier
|
|
# if you do so in /etc/my.cnf, which is preserved during upgrades
|
|
basedir=/usr
|
|
datadir=/var/lib/mysql
|
|
mysql_daemon_user=mysql
|
|
mysql_daemon_group=mysql
|
|
mkdir -m 755 -p /var/run/mysql
|
|
chown $mysql_daemon_user:$mysql_daemon_group /var/run/mysql
|
|
pid_file=/var/run/mysql/mysqld.pid
|
|
socket=/var/run/mysql/mysql.sock
|
|
print_defaults=/usr/bin/my_print_defaults
|
|
log_error=/var/log/mysql/mysqld.log
|
|
|
|
mode=$1 # start or stop
|
|
|
|
log_base="`echo "$log_error" | sed 's|\.log$||'`"
|
|
[ "$log_base" \!= "$log_error" ] || log_base="/var/log/mysql/mysql"
|
|
log_upgrade="${log_base}-upgrade.log"
|
|
log_upgrade_run="${log_base}-upgrade-run.log"
|
|
log_query="${log_base}-query.log"
|
|
|
|
parse_arguments `$print_defaults $defaults mysqld mysql_server`
|
|
export TMPDIR="`cat /var/run/mysql/tmpdir 2> /dev/null`"
|
|
|
|
# Safeguard (relative paths, core dumps..)
|
|
cd "$basedir"
|
|
|
|
case "$1" in
|
|
start)
|
|
# exit gracefully, if we are already running
|
|
"$MYSELF" status >/dev/null && echo -n "Starting service MySQL " && \
|
|
rc_status -v && rc_exit
|
|
|
|
# prepare tmp dir
|
|
if [ "$TMPDIR" ] && [ -d "$TMPDIR" ] && \
|
|
[ "`ls -ld "$TMPDIR" | grep "^drwx------[\\.\+]\?[[:blank:]]\+[0-9]\+[[:blank:]]\+$mysql_daemon_user[[:blank:]]\+$mysql_daemon_group[[:blank:]]\+.*"`" ]; then
|
|
rm -rf "$TMPDIR"
|
|
fi
|
|
TMPDIR="`mktemp -d -p /var/tmp mysql.XXXXXX | tee /var/run/mysql/tmpdir`"
|
|
[ -z "$TMPDIR" ] || chown "$mysql_daemon_user:$mysql_daemon_group" "$TMPDIR"
|
|
[ "`ls -ld "$TMPDIR" | grep "^drwx------[\\.\+]\?[[:blank:]]\+[0-9]\+[[:blank:]]\+$mysql_daemon_user[[:blank:]]\+$mysql_daemon_group[[:blank:]]\+.*"`" ] || {
|
|
echo "Can't create secure $TMPDIR"
|
|
rc_failed; rc_status -v; rc_exit;
|
|
}
|
|
|
|
# Test, if safe_mysqld actually exists
|
|
SAFE_MYSQLD=/usr/bin/mysqld_safe
|
|
test -x $SAFE_MYSQLD || {
|
|
echo "$SAFE_MYSQLD does not exist ";
|
|
rc_failed 5; rc_status -v; rc_exit;
|
|
}
|
|
debug_flags=""
|
|
if test "$MYSQLD_DEBUG" = yes; then
|
|
# add --log, --core-file and --debug
|
|
# but only if not already set in my.cnf
|
|
if ! $print_defaults mysqld | \
|
|
grep -q -e '--log$' -e '--log[[:blank:]=]'
|
|
then
|
|
debug_flags="--log=${log_query}"
|
|
fi
|
|
if ! $print_defaults mysqld | grep -q -e '^--debug\>' &&
|
|
test "$MYSQLD" = /usr/sbin/mysqld-debug
|
|
then
|
|
debug_flags="$debug_flags --debug=d:t:F:L:o,$datadir/mysqld.trace"
|
|
fi
|
|
if ! $print_defaults mysqld | grep -q -e '^--core-file\>'
|
|
then
|
|
debug_flags="$debug_flags --core-file"
|
|
fi
|
|
fi
|
|
|
|
# Creating parent directories for logs
|
|
for i in "$log_upgrade" "$log_query" "$log_error"; do
|
|
log_dir="`dirname "$i"`"
|
|
if [ \! -d "$log_dir" ]; then
|
|
mkdir -p "$log_dir"
|
|
chmod 660 "$log_dir"
|
|
fi
|
|
done
|
|
|
|
# We assume a fresh install if the directory $datadir/mysql
|
|
# does not exist and create the privilege database
|
|
if ! test -d "$datadir/mysql"; then
|
|
echo "Creating MySQL privilege database... "
|
|
mysql_install_db --user="$mysql_daemon_user" --datadir="$datadir" ||{
|
|
rc_failed; rc_status -v; rc_exit
|
|
}
|
|
fi
|
|
check_obsolete
|
|
# Run mysql_upgrade on every package install/upgrade. Not allways
|
|
# necessary, but doesn't do any harm.
|
|
if test -f "$datadir/.run-mysql_upgrade" ; then
|
|
echo >> "$log_upgrade"
|
|
echo "`LANG="" date` - upgrading MySQL..." >> "$log_upgrade"
|
|
echo >> "$log_upgrade"
|
|
echo "Will update MySQL now, if you encounter any problems, please read following file:" | tee -a "$log_upgrade"
|
|
echo " /usr/share/doc/packages/mysql/README.SuSE" | tee -a "$log_upgrade"
|
|
# Check logs for inconsistencies
|
|
SRCLOGS=""
|
|
ALL_SRCLOGS=""
|
|
for i in "$log_error" /var/lib/mysql/mysqld.log \
|
|
/var/log/mysqld.log ; do
|
|
if test -f "$i"; then
|
|
SRCLOGS="$i"
|
|
ALL_SRCLOGS="${ALL_SRCLOGS} ${i}"
|
|
fi
|
|
done
|
|
if [ "${ALL_SRCLOGS}" \!= " ${SRCLOGS}" ]; then
|
|
echo "Log files inconsistency, please merge following files manually:"
|
|
echo $ALL_SRCLOGS | sed 's|[[:blank:]]\+|\n|' | sed 's|^|\t|'
|
|
else
|
|
if [ "$SRCLOGS" ]; then
|
|
[ "$SRCLOGS" = "$log_error" ] || mv "$SRCLOGS" "$log_error"
|
|
fi
|
|
fi
|
|
check_obsolete >> "$log_upgrade"
|
|
# instead of running mysqld --bootstrap, which wouldn't allow
|
|
# us to run mysql_upgrade, we start a full-featured server with
|
|
# --skip-grant-tables and restict access to it by unix
|
|
# permissions of the named socket
|
|
protected="`cat /var/run/mysql/protecteddir 2> /dev/null`"
|
|
if [ -d "$protected" ]; then
|
|
pid="`cat "$protected/mysqld.pid" 2> /dev/null`"
|
|
if [ "$pid" ] && [ -d "/proc/$pid" ] &&
|
|
[ "`readlink "/proc/$pid/exe" | grep "mysql"`" ]; then
|
|
echo "Can't update as another updating process is currently running" | tee -a "$log_upgrade"
|
|
echo "Please check process $pid and terminate it before restarting MySQL" | tee -a "$log_upgrade"
|
|
rc_failed; rc_status -v; rc_exit;
|
|
else
|
|
rm -rf "$protected"
|
|
fi
|
|
fi
|
|
protected="`mktemp -d -p /var/tmp mysql-protected.XXXXXX | tee /var/run/mysql/protecteddir`"
|
|
[ -z "$protected" ] || chown "$mysql_daemon_user:$mysql_daemon_group" "$protected"
|
|
[ "`ls -ld "$protected" | grep "^drwx------[\\.\+]\?[[:blank:]]\+[0-9]\+[[:blank:]]\+$mysql_daemon_user[[:blank:]]\+$mysql_daemon_group[[:blank:]]\+.*"`" ] || {
|
|
echo "Can't create secure $protected" | tee -a "$log_upgrade"
|
|
rc_failed; rc_status -v; rc_exit;
|
|
}
|
|
|
|
echo "Running protected MySQL... " | tee -a "$log_upgrade"
|
|
$SAFE_MYSQLD \
|
|
--mysqld=${MYSQLD#/usr/sbin/} \
|
|
$debug_flags \
|
|
--skip-networking \
|
|
--skip-grant-tables \
|
|
--datadir="$datadir" \
|
|
--user="$mysql_daemon_user" \
|
|
--log-error="$log_upgrade_run" \
|
|
--socket="$protected/mysql.sock" \
|
|
--pid-file="$protected/mysqld.pid" \
|
|
--group="$mysql_daemon_group" &>/dev/null &
|
|
wait_for_socket "$protected/mysql.sock" || {
|
|
echo "error: $protected/mysql.sock file didn't appeared... " | tee -a "$log_upgrade"
|
|
echo " Try checking \"$log_upgrade_run\"... " | tee -a "$log_upgrade"
|
|
rc_failed; rc_status -v; rc_exit;
|
|
}
|
|
echo "Upgrading MySQL... " | tee -a "$log_upgrade"
|
|
/usr/bin/mysql_upgrade \
|
|
--socket="$protected/mysql.sock" | tee -a "$log_upgrade"
|
|
[ "$PIPESTATUS" -ne 0 ] && {
|
|
rc_failed; rc_status -v;
|
|
kill -TERM "`cat $protected/mysqld.pid`"
|
|
rc_exit; }
|
|
kill -TERM "`cat $protected/mysqld.pid`"
|
|
rm -rf "$protected"
|
|
# Fix ownerships and permissions for $datadir
|
|
chmod 750 "$datadir"
|
|
chown -R "$mysql_daemon_user:$mysql_daemon_group" "$datadir"
|
|
rm -f "$datadir/.run-mysql_upgrade" \
|
|
"$datadir"/{update-stamp-*,mysql/stamp-4.1} # used in the past
|
|
chown "$mysql_daemon_user:$mysql_daemon_group" "$log_upgrade"
|
|
chmod 640 "$log_upgrade"
|
|
fi
|
|
|
|
|
|
echo -n "Starting service MySQL "
|
|
|
|
$SAFE_MYSQLD \
|
|
--mysqld=${MYSQLD#/usr/sbin/} \
|
|
$debug_flags \
|
|
--user="$mysql_daemon_user" \
|
|
--pid-file="$pid_file" \
|
|
--socket="$socket" \
|
|
--datadir="$datadir" &>/dev/null &
|
|
|
|
wait_for_socket "$socket" || {
|
|
# let's not treat this as a fatal error
|
|
echo "warning: $socket didn't appear within 30 seconds"
|
|
}
|
|
chmod a+r "$pid_file"
|
|
|
|
# Rmember status and be verbose
|
|
rc_status -v
|
|
;;
|
|
|
|
stop)
|
|
echo -n "Shutting down service MySQL "
|
|
kill_mysql
|
|
if [ "$TMPDIR" ] && [ -d "$TMPDIR" ] && \
|
|
[ "`ls -ld "$TMPDIR" | grep "^drwx------[\\.\+]\?[[:blank:]]\+[0-9]\+[[:blank:]]\+$mysql_daemon_user[[:blank:]]\+$mysql_daemon_group[[:blank:]]\+.*"`" ]; then
|
|
rm -rf "$TMPDIR"
|
|
fi
|
|
# Remember status and be verbose
|
|
rc_status -v
|
|
;;
|
|
|
|
try-restart)
|
|
## Stop the service and if this succeeds (i.e. the
|
|
## service was running before), start it again.
|
|
## Note: try-restart is not (yet) part of LSB (as of 0.7.5)
|
|
"$MYSELF" status >/dev/null && "$MYSELF" restart
|
|
|
|
# Remember status and be quiet
|
|
rc_status
|
|
;;
|
|
|
|
restart|force-reload)
|
|
echo "Restarting service MySQL "
|
|
"$MYSELF" stop
|
|
"$MYSELF" start
|
|
|
|
rc_status
|
|
;;
|
|
|
|
reload)
|
|
echo -n "Reloading service MySQL "
|
|
kill -HUP "`cat "$pid_file"`"
|
|
touch "$pid_file"
|
|
rc_status -v
|
|
;;
|
|
|
|
check|status)
|
|
echo -n "Checking for service MySQL: "
|
|
## Check status with checkproc(8), if process is running
|
|
## checkproc will return with exit status 0.
|
|
|
|
# Status has a slightly different for the status command:
|
|
# 0 - service running
|
|
# 1 - service dead, but /var/run/ pid file exists
|
|
# 2 - service dead, but /var/lock/ lock file exists
|
|
# 3 - service not running
|
|
|
|
# NOTE: checkproc returns LSB compliant status values,
|
|
# but it checks for running binary first and only
|
|
# if it doesn't find running process with proper
|
|
# name it checks pidfile. So we can't use it because
|
|
# akonadi runs it's own database.
|
|
# checkproc -p $pid_file $MYSQLD
|
|
if [ -f "$pid_file" ]; then
|
|
if ! [ -e /proc/version ]; then
|
|
mount -n -t proc proc /proc
|
|
test -e /proc/version || set_return_value 100
|
|
fi
|
|
pid="`cat "$pid_file"`"
|
|
if [ "$pid" ] && [ -d "/proc/$pid" ]; then
|
|
cmd=`cat "/proc/$pid/cmdline" 2> /dev/null`
|
|
exe=`readlink "/proc/$pid/exe" 2> /dev/null`
|
|
if [ "`echo "$exe" | grep "^$MYSQLD"`" ] || [ "`echo "$cmd" | grep "^$MYSQLD"`" ]; then
|
|
set_return_value 0
|
|
else
|
|
set_return_value 1
|
|
fi
|
|
else
|
|
set_return_value 1
|
|
fi
|
|
else
|
|
set_return_value 3
|
|
fi
|
|
rc_status -v
|
|
;;
|
|
|
|
*)
|
|
echo "Usage: $MYSELF {start|stop|status|reload|restart|try-restart|force-reload}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
rc_exit
|
|
|
|
# vim: ft=sh
|