#!/bin/sh # # mysql A very fast and reliable SQL database engine # # chkconfig: 2345 84 25 # # description: A very fast and reliable SQL database engine. # # Source function library . /etc/rc.d/init.d/functions # Get network config . /etc/sysconfig/network # Get service config if [ -f /etc/sysconfig/mysql ]; then . /etc/sysconfig/mysql else nls "Error: %s not found" /etc/sysconfig/mysql nls "%s can't be run." MySQL exit 1 fi [ -z "$BASE_TABLETYPE" ] && BASE_TABLETYPE="InnoDB" if [ -n "$MYSQL_DB_CLUSTERS" ]; then nls "Warning: MYSQL_DB_CLUSTERS is set. It's obsolete. Use %s instead." /etc/mysql/clusters.conf fi if [ -f /etc/mysql/clusters.conf ]; then 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 else nls "Warning: Missing clusters config file %s" /etc/mysql/clusters.conf if [ -z "$MYSQL_DB_CLUSTERS" ]; then nls "Warning: there are no configured clusters." nls "Using default cluster /var/lib/mysql (compatibility mode)" MYSQL_DB_CLUSTERS=/var/lib/mysql fi fi # Check that networking is up if is_yes "${NETWORKING}"; then if [ ! -f /var/lock/subsys/network -a "$1" != stop -a "$1" != status -a "$1" != init ]; then msg_network_down MySQL exit 1 fi else exit 0 fi action="$1" # any db cluster as command line argument? if [ $# -gt 1 ]; then shift # perform action for specified clusters only 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. # # # check for mysql status # # arguments: # $1 - db cluster # $2 - start|stop # # sets variables: # 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="" 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 [ "$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 # MYSQL_CONFIG MYSQL_DATA_DIR MYSQL_USER MYSQL_PIDFILE # # arguments # $1 - db cluster mysqlgetconfig() { clusterdir="$1" # 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 config_file=/etc/mysqld.conf else 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" else config_file="$clusterdir/mysqld.conf" fi fi 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" 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'?" exit 6 fi eval `awk ' /^[ \t]*\[.*\][ \t]*$/ { match($0,/\[.*\]/) section=substr($0, RSTART + 1, RSTART + RLENGTH - 3) } section == "mysqld" && $2 ~ "=" { if ($1 == "datadir") { printf("MYSQL_DATA_DIR=%s;", $3) } else if ($1 == "user") { printf("MYSQL_USER=%s;", $3) } else if ($1 == "pid-file") { printf("MYSQL_PIDFILE=%s;", $3) } else if ($1 == "socket") { printf("MYSQL_SOCKET=%s;", $3) } } ' $config_file` if is_yes "$MYSQL_RA_COMPAT"; then MYSQL_DATA_DIR_SUB="" 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." exit 6 fi if [ -z $MYSQL_USER ]; then echo "$(nls 'MySQL user not configured properly')"'!' >&2 nls "Edit %s and configure it." "$config_file" >&2 exit 6 fi } # start mysql mysqlstart() { clusterdir="$1" mysqlgetconfig "$clusterdir" if [ ! -d "$MYSQL_DATA_DIR/mysql" ]; then nls "MySQL cluster %s not initialized." "$clusterdir" nls "Try \`%s init %s' before start." "$0" "$clusterdir" exit 6 fi msg_starting "MySQL $clusterdir" busy [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0 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 RETVAL=1 died else RETVAL=1 fail fi } # stop mysql mysqlstop() { clusterdir="$1" 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" stop 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" -o "$MYSQL_STATUS" = "starting" ]; then fail else ok fi } # # check for running mysql instances; if any instance is running then # create subsys lock file # mysqlsubsys() { # check for every defined db cluster in sysconfig file for mysqldir in $DB_CLUSTERS; do mysqlstatus "$mysqldir" if [ "$MYSQL_STATUS" = "running" ]; then touch /var/lock/subsys/mysql return fi done rm -f /var/lock/subsys/mysql } mysqlinit() { clusterdir="$1" if [ -f /etc/mysqld.conf ]; then nls "Running in \`no cluster compat' mode: can't initialize database." nls "Move /etc/mysqld.conf away and rerun \`$0 init' (new config will be in $clusterdir)." exit 1 fi if [ -f "$clusterdir/mysqld.conf" ]; then mysqlgetconfig "$clusterdir" else MYSQL_USER="mysql" MYSQL_CLUSTER_DIR="$clusterdir" 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" # Check if not exist init database if [ -d "$MYSQL_DATA_DIR/mysql" ]; then nls "Seems that database is initialized now. Remove by hand %s" "$MYSQL_DATA_DIR/mysql" nls "before initializing database." nls "For now skipping cluster %s." "$clusterdir" return fi show "Creating privilege mysql tables for $MYSQL_DATA_DIR" 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" # Check if hostname is valid if [ -z "$hostname" ]; then deltext fail 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 deltext fail nls "Sorry, the host '%s' could not be looked up." "$hostname" nls "Please configure the 'hostname' command to return a correct hostname." exit 1 fi 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.*\)=.*#\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 ] || [ -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 \ --datadir=$MYSQL_DATA_DIR --user=$MYSQL_USER << END_OF_DATA CREATE DATABASE mysql; use mysql; $(sed -e "s,@ENGINE@,$BASE_TABLETYPE," /usr/share/mysql/init_db.sql) $(sed -e "s,\$hostname,$hostname,g" /usr/share/mysql/init_db-data.sql) END_OF_DATA then ok cat << END_OF_MSG PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL USERS! 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' NOTE: mysql_logrotate password should be placed to $MYSQL_CONFIG in mysqladmin section. See the manual for more instructions. If you want to use new help tables in MySQL 4.1.x then you'll need to import the help data: /usr/bin/mysql -u mysql -p -S $MYSQL_SOCKET mysql < /usr/share/mysql/fill_help_tables.sql END_OF_MSG else fail cat << END_OF_MSG Installation of grant tables FAILED! Examine the logs in $MYSQL_DATA_DIR for more information. You can also try to start the mysqld demon with: /usr/sbin/mysqld --skip-grant & You can use the command line tool /usr/bin/mysql to connect to the mysql database and look at the grant tables: shell> /usr/bin/mysql -u mysql mysql mysql> show tables Try 'mysqld --help' if you have problems with paths. Setting on logging in /etc/mysqld.conf gives you a log in /var/log/mysql/log that may be helpful. The latest information about MySQL is available on the web at http://www.mysql.com/. 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! END_OF_MSG exit 1 fi } # # End of useful functions. # start() { if [ ! -f $MYSQL_ERRLOG ]; then touch $MYSQL_ERRLOG fi chown mysql:mysql $MYSQL_ERRLOG chmod 640 $MYSQL_ERRLOG for mysqldir in $DB_CLUSTERS; do mysqlstatus "$mysqldir" start if [ "$MYSQL_STATUS" = "running" ]; then msg_already_running "MySQL $mysqldir" else mysqlstart "$mysqldir" fi done mysqlsubsys } stop() { for mysqldir in $DB_CLUSTERS; do mysqlstatus "$mysqldir" stop if [ "$MYSQL_STATUS" = "not running" ]; then msg_not_running "MySQL $mysqldir" else mysqlstop "$mysqldir" fi done mysqlsubsys } RETVAL=0 case "$action" in start) start ;; stop) stop ;; status) for mysqldir in $DB_CLUSTERS; do mysqlstatus "$mysqldir" 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) stop start ;; init) for mysqldir in $DB_CLUSTERS; do mysqlinit "$mysqldir" done exit $? ;; flush-logs) for mysqldir in $DB_CLUSTERS; do mysqlgetconfig "$mysqldir" # 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 ;; *) msg_usage "$0 {start|stop|init|restart|force-reload|status}" exit 3 esac exit $RETVAL # vi: shiftwidth=4 tabstop=4