]> git.pld-linux.org Git - packages/mysql.git/blobdiff - mysql.init
- merge initscript improvements from HEAD
[packages/mysql.git] / mysql.init
index 598d8fa2bc4b763ebbdc8898e0d445c30b14c1ed..9d3354cf20eb5ce5bbe7acf19fca1de581ba157b 100644 (file)
@@ -26,7 +26,7 @@ if [ -n "$MYSQL_DB_CLUSTERS" ]; then
 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
@@ -57,12 +57,29 @@ action="$1"
 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.
@@ -73,25 +90,59 @@ MYSQL_ERRLOG=/var/log/mysql/err
 #
 # 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
@@ -105,27 +156,26 @@ mysqlgetconfig() {
 
        # 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
@@ -137,22 +187,19 @@ mysqlgetconfig() {
        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`
 
 
@@ -194,9 +241,19 @@ mysqlstart() {
        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
@@ -211,31 +268,31 @@ mysqlstart() {
 # 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"
 }
 
 #
@@ -290,7 +347,6 @@ mysqlinit() {
        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"
@@ -578,23 +634,26 @@ mysqlinit() {
          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 \
@@ -632,11 +691,11 @@ END_OF_DATA
        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.
@@ -681,9 +740,7 @@ END_OF_MSG
 # End of useful functions.
 #
 
-RETVAL=0
-case "$action" in
-  start)
+start() {
        if [ ! -f $MYSQL_ERRLOG ]; then
                touch $MYSQL_ERRLOG
        fi
@@ -691,7 +748,7 @@ case "$action" in
        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
@@ -699,10 +756,11 @@ case "$action" in
                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
@@ -710,19 +768,33 @@ case "$action" in
                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
This page took 0.056237 seconds and 4 git commands to generate.