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"
- mysqlgetconfig "$clusterdir"
+ 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
nls "Error: config file %s not found" "$config_file"
nls "MySQL can't be run. Did you initialize DB by doing \`$0 init'?"
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`
else
MYSQL_DATA_DIR_SUB="/mysqldb"
fi
-
+
if [ -z "$MYSQL_DATA_DIR" -o "$MYSQL_DATA_DIR" != "${clusterdir}${MYSQL_DATA_DIR_SUB}/db" ]; then
nls "Error: datadir specified in %s should be %s" "$config_file" "$clusterdir${MYSQL_DATA_DIR_SUB}/db"
nls " MySQL can't be run."
exit 6
fi
-
+
if [ -z "$MYSQL_PIDFILE" -o "$MYSQL_PIDFILE" != "$clusterdir${MYSQL_DATA_DIR_SUB}/mysql.pid" ]; then
nls "Error: pid-file specified in %s should be %s" "$config_file" "$clusterdir${MYSQL_DATA_DIR_SUB}/mysql.pid"
nls " MySQL can't be run."
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
-# TODO
-# graceful mysql shutdown with mysqladmin shutdown requires 'shutdown'
-# privilege. create new user mysqlctl or rename mysql_logrotate to mysqlctl
-# and give it both privs (flush-logs and shutdown)?
-
# try graceful shutdown -- send shutdown command
- /usr/bin/mysqladmin --defaults-file=$MYSQL_CONFIG ${MYSQL_SOCKET:+--socket=$MYSQL_SOCKET} shutdown 2>/dev/null
- mysqlstatus "$clusterdir"
+ # 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" stop
- [ "$MYSQL_PID" != "unknown" ] && kill -TERM "$MYSQL_PID" 2> /dev/null
- # 3 seconds
- for nr in 1 2 3; 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"
}
#
MYSQL_DATA_DIR="$clusterdir/mysqldb/db"
MYSQL_PIDFILE="$clusterdir/mysqldb/mysql.pid"
MYSQL_SOCKET="$clusterdir/mysqldb/mysql.sock"
+
+ # this $MYSQL_CONFIG will be created later
+ MYSQL_CONFIG="$MYSQL_CLUSTER_DIR/mysqld.conf"
fi
nls "Initializing cluster %s" "$clusterdir"
show "Creating privilege mysql tables for $MYSQL_DATA_DIR"
busy
- TMP=/tmp TMPDIR=/tmp
+ 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"
-
+
# Check if hostname is valid
if [ -z "$hostname" ]; then
deltext
nls "Sorry, the host name is not configured."
nls "Please configure the 'hostname' command to return a hostname."
exit 1
- elif ! hostname -i >/dev/null 2>&1; then
+ elif ! hostname -i >/dev/null 2>&1; then
deltext
fail
nls "Sorry, the host '%s' could not be looked up." "$hostname"
i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');"
-
+
fi
if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/host.frm
c_tzt="$c_tzt CHARACTER SET utf8"
c_tzt="$c_tzt comment='Time zone transitions';"
fi
-
+
if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone_transition_type.frm
then
c_tztt="$c_tztt CREATE TABLE time_zone_transition_type ("
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 \
$c_tztt
$c_tzls
END_OF_DATA
- then
+ then
ok
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.
-IMPORTANT: The configuration file is mysqld.conf in MYSQL_DB_CLUSTERS directories.
-
END_OF_MSG
- else
+ else
fail
cat << END_OF_MSG
Installation of grant tables FAILED!
may be helpful. The latest information about MySQL is available on the
web at http://www.mysql.com/.
-Please check PLD ftp site for newer versions of this package.
+Please check PLD Linux ftp site for newer versions of this package.
Please consult the MySQL manual section: 'Problems running
mysql_install_db', and the manual section that describes problems on
your OS. Another information source is the MySQL email archive.
Please check all of the above before mailing us! And if you do mail
-us, you MUST use the /usr/bin/mysqlbug script!
+us, you MUST use the /usr/bin/mysqlbug script!
END_OF_MSG
# 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
flush-logs)
for mysqldir in $DB_CLUSTERS; do
mysqlgetconfig "$mysqldir"
- /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" flush-logs
+ # just if mysqld is really running
+ if /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" ping >/dev/null 2>&1; then
+ /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" flush-logs
+ fi
done
;;
*)