LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File rc.mysql-multi of Package mysql-community-server (Project home:smarty12:testing)

#!/bin/bash
# Copyright (c) 1995-2011 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:  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/^[^=]*=//'`" ;;
      --user=*)      mysql_daemon_user="`echo "$arg"  | sed -e 's/^[^=]*=//'`" ;;
      --group=*)     mysql_daemon_group="`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_pid_file
	if [ "$1" ]; then
		test_pid_file="$1"
	else
		test_pid_file="$pid_file"
	fi
	test -e "$test_pid_file" || return 7  # not running
	pid=`cat "$test_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 "$test_pid_file" || return 0
		LC_ALL=C sleep 0.1
	done
	test -e "$test_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
	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`
	mkdir -m 755 -p /var/run/mysql
	chown --no-dereference "$mysql_daemon_user:$mysql_daemon_group" /var/run/mysql
	export TEMPDIR="`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
		unset TMPDIR
		if [ "$TEMPDIR" ] && [ -d "$TEMPDIR" ] && \
			[ "`ls -ld "$TEMPDIR" | grep "^drwx------[\\.\+]\?[[:blank:]]\+[0-9]\+[[:blank:]]\+$mysql_daemon_user[[:blank:]]\+$mysql_daemon_group[[:blank:]]\+.*"`" ]; then
			rm -rf "$TEMPDIR"
		fi
		TEMPDIR="`mktemp -d -p /var/tmp mysql.XXXXXX | tee /var/run/mysql/tmpdir`"
		[ -z "$TEMPDIR" ] || chown --no-dereference "$mysql_daemon_user:$mysql_daemon_group" "$TEMPDIR"
		[ "`ls -ld "$TEMPDIR" | grep "^drwx------[\\.\+]\?[[:blank:]]\+[0-9]\+[[:blank:]]\+$mysql_daemon_user[[:blank:]]\+$mysql_daemon_group[[:blank:]]\+.*"`" ] || {
			echo "Can't create secure $TEMPDIR"
			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"
			fi
			chmod 770 "$log_dir"
			chown -R --no-dereference mysql:mysql "$log_dir"
		done

		MYSQLVER="`echo @MYSQLVER@ | sed 's|\.[0-9]\+$||'`"

		# 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
			}
			echo -n "$MYSQLVER" > "$datadir"/mysql_upgrade_info
		fi
		check_obsolete
		# Run mysql_upgrade on every package install/upgrade. Not always
		# necessary, but doesn't do any harm. On big upgrade, require 
		# user confirmation.
		if [ -f "/var/lib/mysql/.run-mysql_upgrade" ]; then
			if [ \! -f "/var/lib/mysql/.force_upgrade" ] && \
			   [ -f "$datadir/mysql_upgrade_info" ] && \
			   [ -z "`grep "^$MYSQLVER" "$datadir/mysql_upgrade_info" 2> /dev/null`" ]; then
			   echo
			   echo "You are upgrading from different stable version of MySQL!"
			   echo "Make sure you to make backup of your data (mostly $datadir)!"
			   echo
			   echo "If you want to continue upgrading your database, run following commands:"
			   echo
			   echo "   touch /var/lib/mysql/.force_upgrade"
			   echo "   rcmysql restart"
			   echo
			   rc_failed;  rc_status -v; rc_exit

			fi
			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"
			sed -i -e 's|^\([^#]*skip-locking\)|\1\nskip-external-locking|' \
			       -e 's|^\([^#]*skip-federated\)|#\1|' /etc/my.cnf
			# 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"
						touch /var/lib/mysql/.run-mysql_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`"
			export TMPDIR="$TEMPDIR"
			
			# Run upgrade, double check
			# We need to restart mysql every time as programs
			# reloads privileges tables, so we can get lock out
			for cmd in "/usr/bin/mysql_upgrade"                  \
			           "/usr/bin/mysql_upgrade"; do
			[ -z "$protected" ] || chown --no-dereference "$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"
				touch /var/lib/mysql/.run-mysql_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"
				touch /var/lib/mysql/.run-mysql_upgrade
				rc_failed; rc_status -v; rc_exit;
			}
			if [ "`grep "Upgrading MySQL..." "$log_upgrade"`" ]; then
				echo "Problems should be fixed now."
				echo "Rechecking whether everything is Ok... " | tee -a "$log_upgrade"
				LANG=C $cmd --no-defaults --force \
					--socket="$protected/mysql.sock" | \
					sed -e 's|^|\ \ \ |'             | \
					tee -a "$log_upgrade"
			else
				echo "Upgrading MySQL... " | tee -a "$log_upgrade"
					LANG=C $cmd --no-defaults --force \
						--socket="$protected/mysql.sock"               | \
						sed -e 's|^|\ \ \ |'                             \
						    -e 's|error|info|'                           \
						    -e 's|\(Table\ upgrade\ required.\).*|\1|' | \
						tee -a "$log_upgrade"
			fi
			[ "$PIPESTATUS" -ne 0 ] && {
				rc_failed; rc_status -v;
				kill_mysql "$protected/mysqld.pid"
				rc_exit; }

			kill_mysql "$protected/mysqld.pid" || {
				echo "error: Can't stop protected MySQL... " | tee -a "$log_upgrade"
				rc_failed; rc_status -v;
				kill_mysql "$protected/mysqld.pid"
				rc_exit; }

			# Everything went fine
			if [ -z "`grep REPAIR "$log_upgrade"`" ] && \
			   [ -z "`grep "Table\ upgrade\ required" "$log_upgrade"`" ]; then
			   	break
			fi

			done # end of upgrade

			rm -rf "$protected"
			# Fix ownerships and permissions for $datadir
			chmod 750 "$datadir"
			chown -R --no-dereference "$mysql_daemon_user:$mysql_daemon_group" "$datadir"
			rm -f /var/adm/update-messages/mysql-*
			rm -f /var/lib/mysql/.run-mysql_upgrade
			rm -f /var/lib/mysql/.force_upgrade
			rm -f "$datadir"/{update-stamp-*,mysql/stamp-4.1} # used in the past
			chown --no-dereference "$mysql_daemon_user:$mysql_daemon_group" "$log_upgrade"
			chmod 640 "$log_upgrade"
		fi 

		export TMPDIR="$TEMPDIR"

		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 [ "$TEMPDIR" ] && [ -d "$TEMPDIR" ] && \
			[ "`ls -ld "$TEMPDIR" | grep "^drwx------[\\.\+]\?[[:blank:]]\+[0-9]\+[[:blank:]]\+$mysql_daemon_user[[:blank:]]\+$mysql_daemon_group[[:blank:]]\+.*"`" ]; then
			rm -rf "$TEMPDIR"
		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