LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File mysql-systemd-helper of Package mariadb (Project home:jayvdb:toggl)

#!/bin/bash
die() {
	echo "$1"
	exit 1
}

# Read options from config file
read_config() {
	# Initial settings
	MYSQLVER="$(echo @MYSQLVER@ | sed 's|\.[0-9]\+$||')"
	mysql_daemon_user=mysql
	mysql_daemon_group=mysql
	if [[ -z "$INSTANCE" ]]; then
		datadir=/var/lib/mysql
		socket="/run/mysql/mysql.sock"
	else
		datadir="/var/lib/mysql-$INSTANCE"
		socket="/run/mysql/mysql.${INSTANCE}.sock"
	fi

	# Read options - important for multi setup
	if [[ -n "$INSTANCE" ]]; then
		opts="$(/usr/bin/my_print_defaults mysqld mysqld_multi "$INSTANCE")"
		tmp_opts="$opts"
		config="/etc/my${INSTANCE}.cnf"
	else
		opts="$(/usr/bin/my_print_defaults mysqld)"
		tmp_opts="$opts"
		config="/etc/my.cnf"
	fi

	# Update local variables according to the settings from config
	for arg in $tmp_opts; do
		case "$arg" in
			--basedir=*)   basedir="$(echo "$arg"            | sed -e 's/^[^=]*=//')" ;;
			--socket=*)    socket="$(echo "$arg"             | sed -e 's/^[^=]*=//')" ;;
			--datadir=*)   datadir="$(echo "$arg"            | sed -e 's/^[^=]*=//')" ;;
			--user=*)      mysql_daemon_user="$(echo "$arg"  | sed -e 's/^[^=]*=//')" ;;
		esac
	done

	# work-around for lost+found directory in $datadir (bug #986251)
	if [ -d "$datadir/lost+found" ]
	then
		ignore_db_dir="--ignore-db-dir=lost+found"
	else
		ignore_db_dir=""
	fi
}

# Create new empty database if needed
mysql_install() {
	if [[ ! -d "$datadir/mysql" ]]; then
		echo "Creating MySQL privilege database... "
		mysql_install_db --user="$mysql_daemon_user" --datadir="$datadir" || \
		die "Creation of MySQL databse in $datadir failed"
		echo -n "$MYSQLVER" > "$datadir"/mysql_upgrade_info
	fi
}

# Upgrade database if needed
mysql_upgrade() {
	# Run mysql_upgrade on every package install/upgrade. Not always
	# necessary, but doesn't do any harm.
	if [[ -f "$datadir/.run-mysql_upgrade" ]]; then
		echo "Checking MySQL configuration for obsolete options..."
		sed -i -e 's|^\([[:blank:]]*\)skip-locking|\1skip-external-locking|' \
		       -e 's|^\([[:blank:]]*skip-federated\)|#\1|' /etc/my.cnf

		# 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

		echo "Trying to run upgrade of MySQL databases..."

		# Check whether upgrade process is not already running
		protected="$(cat "/run/mysql/protecteddir.$INSTANCE" 2> /dev/null)"
		if [[ -n "$protected" && -d "$protected" ]]; then
			pid="$(cat "$protected/mysqld.pid" 2> /dev/null)"
			if [[ "$pid" && -d "/proc/$pid" ]] &&
			   [[ $(readlink "/proc/$pid/exe" | grep -q "mysql") ]]; then
				die "Another upgrade in already in progress!"
			else
				echo "Stale files from previous upgrade detected, cleaned them up"
				rm -rf "$protected"
				rm -f "/run/mysql/protecteddir.$INSTANCE"
			fi
		fi
		protected="$(mktemp -d -p /var/tmp mysql-protected.XXXXXX | tee "/run/mysql/protecteddir.$INSTANCE")"
		[ -n "$protected" ] || die "Can't create a tmp dir '$protected'"

		# Create a secure tmp dir
		chown --no-dereference "$mysql_daemon_user:$mysql_daemon_group" "$protected" || die "Failed to set group/user to '$protected'"
		chmod 0700  "$protected" || die "Failed to set permissions to '$protected'"

		# Run protected MySQL accessible only though socket in our directory
		echo "Running protected MySQL... "
		/usr/sbin/mysqld \
			--defaults-file="$config" \
			--user="$mysql_daemon_user" \
			--skip-networking \
			--skip-grant-tables \
			$ignore_db_dir \
			--log-error="$protected/log_upgrade_run" \
			--socket="$protected/mysql.sock" \
			--pid-file="$protected/mysqld.pid" &

		mysql_wait "$protected/mysql.sock" || die "MySQL didn't start, can't continue"

		# Run upgrade itself
		echo "Running upgrade itself..."
		echo "It will do some chek first and report all errors and tries to correct them"
		echo
		if /usr/bin/mysql_upgrade --no-defaults --force --socket="$protected/mysql.sock"; then
			echo "Everything upgraded successfully"
			up_ok=""
			rm -f "$datadir/.run-mysql_upgrade"
			[[ $(grep -q "^$MYSQLVER" "$datadir/mysql_upgrade_info" 2> /dev/null) ]] || \
				echo -n "$MYSQLVER" > "$datadir/mysql_upgrade_info"
		else
			echo "Upgrade failed"
			up_ok="false"
		fi

		# Shut down MySQL
		echo "Shuting down protected MySQL"
		kill "$(cat "$protected/mysqld.pid")"
		for i in {1..30}; do
			/usr/bin/mysqladmin --socket="$protected/mysql.sock" ping > /dev/null 2>&1 || break
		done
		/usr/bin/mysqladmin --socket="$protected/mysql.sock" ping > /dev/null 2>&1 && kill -9 "$(cat "$protected/mysqld.pid")"

		# Cleanup
		echo "Final cleanup"
		if [[ -z "$up_ok" ]]; then
			rm -rf "$protected" "/run/mysql/protecteddir.$INSTANCE"
		else 
			die "Something failed during upgrade, please check logs"
		fi
	fi
}

mysql_wait() {
	[[ -z "$1" ]] || socket="$1"
	echo "Waiting for MySQL to start"
	for i in {1..60}; do
		/usr/bin/mysqladmin --socket="$socket" ping > /dev/null 2>&1 && break
		sleep 1
	done
	if /usr/bin/mysqladmin --socket="$socket" ping > /dev/null 2>&1; then
		echo "MySQL is alive"
		return 0
	else
		echo "MySQL is still dead"
		return 1
	fi
}

mysql_start() {
	exec /usr/sbin/mysqld \
		--defaults-file="$config" \
		$ignore_db_dir \
		--user="$mysql_daemon_user"
}

# We rely on output in english at some points
LC_ALL=C

# set the default umask bsc#1020976
umask 077

INSTANCE="$2"
read_config
mkdir -p /run/mysql
# fix permissions for /run/mysql (bsc#1038740)
chmod 755 /run/mysql
chown --no-dereference "$mysql_daemon_user:$mysql_daemon_group" /run/mysql
case "$1" in
	install)
		mysql_install ;;
	upgrade)
		mysql_upgrade ;;
	start)
		mysql_start ;;
	wait)
		mysql_wait ;;
	*)
		echo "Supported commands are:"
		echo "   install - creates empty database if needed"
		echo "   upgrade - tries to migrate data to newer version if needed"
		echo "   start   - tries to start instance"
		echo "   wait    - waits till instance is pingable"
		echo "All commands can take extra argument which is group from 'mysqld_multi' you want to work with"
		;;
esac