fi
if [ -f /etc/mysql/clusters.conf ]; then
- MYSQL_DB_CLUSTERS=$(grep -v '^#' /etc/mysql/clusters.conf | cut -s -f 2 -d '=')
+ MYSQL_DB_CLUSTERS=$(awk -F= '!/^#/{print $2}' /etc/mysql/clusters.conf)
if [ -z "$MYSQL_DB_CLUSTERS" ]; then
nls "Warning: there are no configured clusters."
fi
if [ $# -gt 1 ]; then
shift
# perform action for specified clusters only
- DB_CLUSTERS="$@"
+ for a in "$@"; do
+ # try auto resolving from /etc/mysql/clusters.conf
+ if [[ "$a" != /* ]]; then
+ m=$(awk -va="$a" -F= 'substr($0, 1, length(a)) == a {print $1}' /etc/mysql/clusters.conf)
+ if [ -z "$m" ]; then
+ echo >&2 "Cluster name '$a' did not match anything!"
+ exit 1
+ fi
+ if [ $(echo "$m" | wc -l) -gt 1 ]; then
+ echo >&2 "Cluster name '$a' ambiguous:" $m
+ exit 1
+ fi
+ a=$(awk -va="$a" -F= 'substr($0, 1, length(a)) == a {print $2}' /etc/mysql/clusters.conf)
+ fi
+ DB_CLUSTERS="$DB_CLUSTERS $a"
+ done
else
DB_CLUSTERS="$MYSQL_DB_CLUSTERS"
fi
MYSQL_ERRLOG=/var/log/mysql/err
+MYSQL_START_WAIT_TIME=${MYSQL_START_WAIT_TIME:-15}
+MYSQL_STOP_WAIT_TIME=${MYSQL_STOP_WAIT_TIME:-900}
#
# Useful functions.
#
# arguments:
# $1 - db cluster
+# $2 - start|stop
#
# sets variables:
-# MYSQL_STATUS = running | not running | died
+# MYSQL_STATUS = starting | running | not running | died
# MYSQL_PID = pid of mysqld process
#
mysqlstatus() {
clusterdir="$1"
+ mode="$2"
+
mysqlgetconfig "$clusterdir"
MYSQL_STATUS="not running"
MYSQL_PID="unknown"
+ MYSQL_PIDFILE_PID=""
+ MYSQL_GREP_PID=""
- [ -f "$MYSQL_PIDFILE" ] && MYSQL_PID=$(cat "$MYSQL_PIDFILE")
+ if [ -f "$MYSQL_PIDFILE" ]; then
+ MYSQL_PIDFILE_PID=$(cat "$MYSQL_PIDFILE")
+ fi
+
+ if [ -n "$MYSQL_PIDFILE_PID" ]; then
+ MYSQL_PID=$MYSQL_PIDFILE_PID
+ if [ ! -d "/proc/$MYSQL_PID" ]; then
+ MYSQL_STATUS="died"
+ return
+ elif (grep -qa "$MYSQL_PIDFILE" /proc/$MYSQL_PID/cmdline 2> /dev/null); then
+ MYSQL_STATUS="running"
+ return
+ fi
+ fi
- if [ ! -d "/proc/$MYSQL_PID" -a "$MYSQL_PID" != "unknown" ]; then
- MYSQL_STATUS="died"
- elif [ -d "/proc/$MYSQL_PID" ]; then
- grep -qa "$MYSQL_PIDFILE" /proc/$MYSQL_PID/cmdline && MYSQL_STATUS="running" || MYSQL_STATUS="not running"
+ if [ "$mode" = "start" ]; then
+ MYSQL_GREP_PID=$(grep -lE "^/usr/sbin/mysqld.*${MYSQL_PIDFILE}" /proc/[0-9]*/cmdline 2> /dev/null | awk -F "/" '{ print $3; exit; }')
+ if [ -n "$MYSQL_GREP_PID" ]; then
+ MYSQL_PID=$MYSQL_GREP_PID
+ if (grep -qa "$MYSQL_PIDFILE" /proc/$MYSQL_PID/cmdline 2> /dev/null); then
+ if [ -f "$MYSQL_PIDFILE" ]; then
+ MYSQL_PIDFILE_PID=$(cat "$MYSQL_PIDFILE")
+ fi
+ if [ -n "$MYSQL_PIDFILE_PID" ]; then
+ MYSQL_PID=$MYSQL_PIDFILE_PID
+ MYSQL_STATUS="running"
+ return
+ else
+ MYSQL_STATUS="starting"
+ return
+ fi
+ fi
+ fi
fi
+
+ # else default, "not running"
}
# get mysql configuration in variables
# emulate old behaviour if only one cluster specified
if [ "$clusterdir" = "$MYSQL_DB_CLUSTERS" -a "$clusterdir" = "/var/lib/mysql" -a -f /etc/mysqld.conf ]; then
- MYSQL_RA_COMPAT=yes; export MYSQL_RA_COMPAT
+ MYSQL_RA_COMPAT=yes
config_file=/etc/mysqld.conf
else
- # TODO: convert this piece of crap to awk
- config=`grep -v "^#" /etc/mysql/clusters.conf | grep "${clusterdir}$" | cut -s -f 1 -d '='`
- if echo "$config" | grep -q '^/'; then
+ config=$(awk -F= -vclusterdir="$clusterdir" '!/^#/{ if (clusterdir == $2) print $1}' /etc/mysql/clusters.conf)
+ if [[ $config = /* ]]; then
config_file="$config"
elif [ -f "/etc/mysql/$config" ]; then
- config_file=/etc/mysql/$config
+ config_file="/etc/mysql/$config"
else
config_file="$clusterdir/mysqld.conf"
fi
fi
- MYSQL_CLUSTER_DIR="$clusterdir"; export MYSQL_CLUSTER_DIR
+ MYSQL_CLUSTER_DIR="$clusterdir"
if [ -z "$config_file" ]; then
nls "Error: Can't find config file for %s cluster" "$clusterdir"
exit 6
else
- MYSQL_CONFIG="$config_file"; export MYSQL_CONFIG
+ MYSQL_CONFIG="$config_file"
fi
if [ ! -f "$config_file" ]; then
eval `awk '
/^[ \t]*\[.*\][ \t]*$/ {
match($0,/\[.*\]/)
- section=substr($0,RSTART+1,RSTART+RLENGTH-3)
+ section=substr($0, RSTART + 1, RSTART + RLENGTH - 3)
}
-section=="mysqld" && $2~"=" {
- if ($1=="datadir") {
+section == "mysqld" && $2 ~ "=" {
+ if ($1 == "datadir") {
printf("MYSQL_DATA_DIR=%s;", $3)
- } else if ($1=="user") {
+ } else if ($1 == "user") {
printf("MYSQL_USER=%s;", $3)
- } else if ($1=="pid-file") {
+ } else if ($1 == "pid-file") {
printf("MYSQL_PIDFILE=%s;", $3)
- } else if ($1=="socket") {
+ } else if ($1 == "socket") {
printf("MYSQL_SOCKET=%s;", $3)
}
}
-END {
- print "export MYSQL_DATA_DIR MYSQL_USER MYSQL_PIDFILE MYSQL_SOCKET"
-}
' $config_file`
msg_starting "MySQL $clusterdir"
busy
[ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
- TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} /usr/bin/setsid /usr/sbin/mysqld --defaults-file=$MYSQL_CONFIG --datadir=$MYSQL_DATA_DIR --pid-file=$MYSQL_PIDFILE >> $MYSQL_ERRLOG 2>&1 &
- sleep 2
- mysqlstatus "$clusterdir"
+ rm -f "$MYSQL_PIDFILE"
+ TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} /usr/bin/setsid /usr/sbin/mysqld --defaults-file=$MYSQL_CONFIG --datadir=$MYSQL_DATA_DIR --pid-file=$MYSQL_PIDFILE $MYSQL_OPTIONS >> $MYSQL_ERRLOG 2>&1 &
+ sleep 0.2
+ mysqlstatus "$clusterdir" start
+ # it takes longer for mysqld to start and create pidfile if it has to recover innodb transactions
+ if [ "$MYSQL_STATUS" = "starting" ]; then
+ for nr in $(seq 1 $(($MYSQL_START_WAIT_TIME*10))); do
+ [ -f "$MYSQL_PIDFILE" ] && break
+ sleep 0.1
+ done
+ fi
+
+ mysqlstatus "$clusterdir" start
if [ "$MYSQL_STATUS" = "running" -a "$MYSQL_PID" != "unknown" ]; then
ok
elif [ "$MYSQL_STATUS" = "died" ]; then
# stop mysql
mysqlstop() {
clusterdir="$1"
- mysqlstatus "$clusterdir"
+ mysqlstatus "$clusterdir" stop
msg_stopping "MySQL $clusterdir"
busy
# try graceful shutdown -- send shutdown command
# requires mysql_logrotate user proper privs
/usr/bin/mysqladmin --defaults-file=$MYSQL_CONFIG ${MYSQL_SOCKET:+--socket=$MYSQL_SOCKET} shutdown >/dev/null 2>&1
- mysqlstatus "$clusterdir"
+ mysqlstatus "$clusterdir" stop
- [ "$MYSQL_PID" != "unknown" ] && kill -TERM "$MYSQL_PID" 2> /dev/null
- # 15 seconds
- for nr in $(seq 1 15); do
- [ -d "/proc/$MYSQL_PID" ] && sleep 1
- done
- mysqlstatus "$clusterdir"
+ if [ "$MYSQL_PID" != "unknown" ]; then
+ kill -TERM "$MYSQL_PID" 2> /dev/null
+ for nr in $(seq 1 $(($MYSQL_STOP_WAIT_TIME*10))); do
+ [ -d "/proc/$MYSQL_PID" ] || break
+ sleep 0.1
+ done
+ fi
+
+ mysqlstatus "$clusterdir" stop
if [ "$MYSQL_STATUS" = "died" ]; then
died
- elif [ "$MYSQL_STATUS" = "running" ]; then
+ elif [ "$MYSQL_STATUS" = "running" -o "$MYSQL_STATUS" = "starting" ]; then
fail
else
ok
fi
-
- # FIXME: should let mysqld remove pid by itself?
- rm -f "$MYSQL_PIDFILE"
}
#
busy
TMP=/tmp TMPDIR=/tmp
-
# Install this in the user table, too
hostname="`hostname --fqdn 2> /dev/null | tr -d '[:space:]'`"
[ -z "$hostname" ] && hostname="localhost-unknown"
c_tzls="$c_tzls comment='Leap seconds information for time zones';"
fi
- mkdir -p "$MYSQL_DATA_DIR" > /dev/null 2>&1
+ mkdir -p "$MYSQL_DATA_DIR"
# Using mysql:mysql for MYSQL_CLUSTER_DIR is creating SECURITY hole, root:root is proper
chown root:root "$MYSQL_CLUSTER_DIR"
chown mysql:mysql "$MYSQL_CLUSTER_DIR/mysqldb" "$MYSQL_DATA_DIR" > /dev/null 2>&1
chmod 751 "$MYSQL_CLUSTER_DIR" "$MYSQL_CLUSTER_DIR/mysqldb"
if [ -f /usr/share/mysql/mysqld.conf -a ! -f "$MYSQL_CLUSTER_DIR/mysqld.conf" ]; then
- sed -e "s#datadir.*=.*#datadir = $MYSQL_DATA_DIR#g" \
- -e "s#pid-file.*=.*#pid-file = $MYSQL_PIDFILE#g" \
- -e "s#socket.*=.*#socket = $MYSQL_SOCKET#g" \
- /usr/share/mysql/mysqld.conf > "$MYSQL_CLUSTER_DIR/mysqld.conf"
+ sed -e "
+ s#\(datadir.*\)=.*#\1= $MYSQL_DATA_DIR#g;
+ s#\(pid-file.*\)=.*#\1= $MYSQL_PIDFILE#g;
+ s#\(socket.*\)=.*#\1= $MYSQL_SOCKET#g;
+ s#@clusterdir@#$MYSQL_CLUSTER_DIR#g;
+ " /usr/share/mysql/mysqld.conf > "$MYSQL_CLUSTER_DIR/mysqld.conf"
chown root:root "$MYSQL_CLUSTER_DIR/mysqld.conf"
chmod 640 "$MYSQL_CLUSTER_DIR/mysqld.conf"
fi
- if [ ! -e /var/lib/mysql/mysql.sock ]; then
- ln -s "$MYSQL_SOCKET" /var/lib/mysql/mysql.sock
+ if [ ! -e /var/lib/mysql/mysql.sock ] || [ -L /var/lib/mysql/mysql.sock ] && [ -z "$(readlink /var/lib/mysql/mysql.sock)" ]; then
+ sock=${MYSQL_SOCKET#/var/lib/mysql/} # make it relative if possible
+ ln -s "$sock" /var/lib/mysql/mysql.sock
fi
if /usr/sbin/mysqld --bootstrap --skip-grant-tables \
cat << END_OF_MSG
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL USERS!
-This is done (after starting database) with:
+This is done (after starting database; press enter when asked for password) with:
-/usr/bin/mysqladmin -u mysql -S $MYSQL_SOCKET password 'password'
-/usr/bin/mysqladmin -h $hostname -u mysql -S $MYSQL_SOCKET password 'password'
-/usr/bin/mysqladmin -u mysql_logrotate -S $MYSQL_SOCKET password 'password'
+/usr/bin/mysqladmin -u mysql -p -S $MYSQL_SOCKET password 'password'
+/usr/bin/mysqladmin -h $hostname -u mysql -p -S $MYSQL_SOCKET password 'password'
+/usr/bin/mysqladmin -u mysql_logrotate -p -S $MYSQL_SOCKET password 'password'
NOTE: mysql_logrotate password should be placed to $MYSQL_CONFIG in
mysqladmin section. See the manual for more instructions.
# End of useful functions.
#
-RETVAL=0
-case "$action" in
- start)
+start() {
if [ ! -f $MYSQL_ERRLOG ]; then
touch $MYSQL_ERRLOG
fi
chmod 640 $MYSQL_ERRLOG
for mysqldir in $DB_CLUSTERS; do
- mysqlstatus "$mysqldir"
+ mysqlstatus "$mysqldir" start
if [ "$MYSQL_STATUS" = "running" ]; then
msg_already_running "MySQL $mysqldir"
else
fi
done
mysqlsubsys
- ;;
- stop)
+}
+
+stop() {
for mysqldir in $DB_CLUSTERS; do
- mysqlstatus "$mysqldir"
+ mysqlstatus "$mysqldir" stop
if [ "$MYSQL_STATUS" = "not running" ]; then
msg_not_running "MySQL $mysqldir"
else
fi
done
mysqlsubsys
+}
+
+RETVAL=0
+case "$action" in
+ start)
+ start
+ ;;
+ stop)
+ stop
;;
status)
- status mysqld
for mysqldir in $DB_CLUSTERS; do
mysqlstatus "$mysqldir"
- echo "MySQL cluster $mysqldir: $MYSQL_STATUS"
+ if [ "$MYSQL_STATUS" = "running" ]; then
+ show "MySQL cluster %s, PID %s" "$mysqldir" "$MYSQL_PID"
+ progress "$MYSQL_STATUS"
+ else
+ show "MySQL cluster %s" "$mysqldir"
+ progress "$MYSQL_STATUS" "$CFAIL"
+ fi
+ echo
done
exit $?
;;
restart|force-reload)
- $0 stop $DB_CLUSTERS
- $0 start $DB_CLUSTERS
- exit $?
+ stop
+ start
;;
init)
for mysqldir in $DB_CLUSTERS; do