Convert to systemd startup support

This commit is contained in:
Tom Lane 2011-07-27 15:13:15 -04:00 committed by Michal Schorm
parent c606a777c1
commit f316512a73
6 changed files with 239 additions and 241 deletions

View File

@ -1,228 +0,0 @@
#!/bin/sh
#
# mysqld This shell script takes care of starting and stopping
# the MySQL subsystem (mysqld).
#
# chkconfig: - 64 36
# description: MySQL database server.
# processname: mysqld
# config: /etc/my.cnf
# pidfile: /var/run/mysqld/mysqld.pid
### BEGIN INIT INFO
# Provides: mysqld
# Required-Start: $local_fs $remote_fs $network $named $syslog $time
# Required-Stop: $local_fs $remote_fs $network $named $syslog $time
# Short-Description: start and stop MySQL server
# Description: MySQL database server
### END INIT INFO
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
exec="/usr/bin/mysqld_safe"
prog="mysqld"
# Set timeouts here so they can be overridden from /etc/sysconfig/mysqld
STARTTIMEOUT=120
STOPTIMEOUT=60
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
lockfile=/var/lock/subsys/$prog
# extract value of a MySQL option from config files
# Usage: get_mysql_option SECTION VARNAME DEFAULT
# result is returned in $result
# We use my_print_defaults which prints all options from multiple files,
# with the more specific ones later; hence take the last match.
get_mysql_option(){
result=`/usr/bin/my_print_defaults "$1" | sed -n "s/^--$2=//p" | tail -n 1`
if [ -z "$result" ]; then
# not found, use default
result="$3"
fi
}
get_mysql_option mysqld datadir "/var/lib/mysql"
datadir="$result"
get_mysql_option mysqld socket "$datadir/mysql.sock"
socketfile="$result"
get_mysql_option mysqld_safe log-error "/var/log/mysqld.log"
errlogfile="$result"
get_mysql_option mysqld_safe pid-file "/var/run/mysqld/mysqld.pid"
mypidfile="$result"
start(){
[ -x $exec ] || exit 5
# check to see if it's already running
RESPONSE=`/usr/bin/mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1`
if [ $? = 0 ]; then
# already running, do nothing
action $"Starting $prog: " /bin/true
ret=0
elif echo "$RESPONSE" | grep -q "Access denied for user"
then
# already running, do nothing
action $"Starting $prog: " /bin/true
ret=0
else
# prepare for start
touch "$errlogfile"
chown mysql:mysql "$errlogfile"
chmod 0640 "$errlogfile"
[ -x /sbin/restorecon ] && /sbin/restorecon "$errlogfile"
if [ ! -d "$datadir/mysql" ] ; then
# First, make sure $datadir is there with correct permissions
if [ ! -e "$datadir" -a ! -h "$datadir" ]
then
mkdir -p "$datadir" || exit 1
fi
chown mysql:mysql "$datadir"
chmod 0755 "$datadir"
[ -x /sbin/restorecon ] && /sbin/restorecon "$datadir"
# Now create the database
action $"Initializing MySQL database: " /usr/bin/mysql_install_db --datadir="$datadir" --user=mysql
ret=$?
chown -R mysql:mysql "$datadir"
if [ $ret -ne 0 ] ; then
return $ret
fi
fi
chown mysql:mysql "$datadir"
chmod 0755 "$datadir"
# Pass all the options determined above, to ensure consistent behavior.
# In many cases mysqld_safe would arrive at the same conclusions anyway
# but we need to be sure. (An exception is that we don't force the
# log-error setting, since this script doesn't really depend on that,
# and some users might prefer to configure logging to syslog.)
# Note: set --basedir to prevent probes that might trigger SELinux
# alarms, per bug #547485
$exec --datadir="$datadir" --socket="$socketfile" \
--pid-file="$mypidfile" \
--basedir=/usr --user=mysql >/dev/null 2>&1 &
safe_pid=$!
# Spin for a maximum of N seconds waiting for the server to come up;
# exit the loop immediately if mysqld_safe process disappears.
# Rather than assuming we know a valid username, accept an "access
# denied" response as meaning the server is functioning.
ret=0
TIMEOUT="$STARTTIMEOUT"
while [ $TIMEOUT -gt 0 ]; do
RESPONSE=`/usr/bin/mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1`
mret=$?
if [ $mret -eq 0 ]; then
break
fi
# exit codes 1, 11 (EXIT_CANNOT_CONNECT_TO_SERVICE) are expected,
# anything else suggests a configuration error
if [ $mret -ne 1 -a $mret -ne 11 ]; then
echo "$RESPONSE"
echo "Cannot check for MySQL Daemon startup because of mysqladmin failure."
ret=1
break
fi
echo "$RESPONSE" | grep -q "Access denied for user" && break
if ! /bin/kill -0 $safe_pid 2>/dev/null; then
echo "MySQL Daemon failed to start."
ret=1
break
fi
sleep 1
let TIMEOUT=${TIMEOUT}-1
done
if [ $TIMEOUT -eq 0 ]; then
echo "Timeout error occurred trying to start MySQL Daemon."
ret=1
fi
if [ $ret -eq 0 ]; then
action $"Starting $prog: " /bin/true
touch $lockfile
else
action $"Starting $prog: " /bin/false
fi
fi
return $ret
}
stop(){
if [ ! -f "$mypidfile" ]; then
# not running; per LSB standards this is "ok"
action $"Stopping $prog: " /bin/true
return 0
fi
MYSQLPID=`cat "$mypidfile"`
if [ -n "$MYSQLPID" ]; then
/bin/kill "$MYSQLPID" >/dev/null 2>&1
ret=$?
if [ $ret -eq 0 ]; then
TIMEOUT="$STOPTIMEOUT"
while [ $TIMEOUT -gt 0 ]; do
/bin/kill -0 "$MYSQLPID" >/dev/null 2>&1 || break
sleep 1
let TIMEOUT=${TIMEOUT}-1
done
if [ $TIMEOUT -eq 0 ]; then
echo "Timeout error occurred trying to stop MySQL Daemon."
ret=1
action $"Stopping $prog: " /bin/false
else
rm -f $lockfile
rm -f "$socketfile"
action $"Stopping $prog: " /bin/true
fi
else
action $"Stopping $prog: " /bin/false
fi
else
# failed to read pidfile, probably insufficient permissions
action $"Stopping $prog: " /bin/false
ret=4
fi
return $ret
}
restart(){
stop
start
}
condrestart(){
[ -e $lockfile ] && restart || :
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $prog
;;
restart)
restart
;;
condrestart|try-restart)
condrestart
;;
reload)
exit 3
;;
force-reload)
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?

View File

@ -1,6 +1,9 @@
Name: mysql
Version: 5.5.14
Release: 2%{?dist}
Release: 3%{?dist}
# Update this whenever F15 gets rebased; it must be NVR-greater than F15 pkg:
%global first_systemd_version 5.5.14-3
Summary: MySQL client programs and shared libraries
Group: Applications/Databases
URL: http://www.mysql.com
@ -20,7 +23,6 @@ Source0: mysql-%{version}-nodocs.tar.gz
# the tarball into the current directory:
# ./generate-tarball.sh $VERSION
Source1: generate-tarball.sh
Source2: mysql.init
Source3: my.cnf
Source4: scriptstub.c
Source5: my_config.h
@ -29,6 +31,9 @@ Source7: README.mysql-license
Source8: libmysql.version
Source9: mysql-embedded-check.c
Source10: mysql.tmpfiles.d
Source11: mysqld.service
Source12: mysqld-prepare-db-dir
Source13: mysqld-wait-ready
# Working around perl dependency checking bug in rpm FTTB. Remove later.
Source999: filter-requires-mysql.sh
@ -45,6 +50,7 @@ Patch10: mysql-embedded-crash.patch
Patch11: mysql-plugin-bool.patch
Patch12: mysql-s390-tsc.patch
Patch13: mysql-openssl-test.patch
Patch14: mysqld-nowatch.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: perl, readline-devel, openssl-devel
@ -54,6 +60,7 @@ BuildRequires: systemtap-sdt-devel
BuildRequires: time procps
# Socket and Time::HiRes are needed to run regression tests
BuildRequires: perl(Socket), perl(Time::HiRes)
BuildRequires: systemd-units
Requires: grep, fileutils
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
@ -96,11 +103,16 @@ Requires: sh-utils
Requires(pre): /usr/sbin/useradd
Requires(post): chkconfig
Requires(preun): chkconfig
# This is for /sbin/service
Requires(preun): initscripts
Requires(postun): initscripts
# This is for /etc/tmpfiles.d
# We require this to be present for /etc/tmpfiles.d
Requires: systemd-units
# Make sure it's there when scriptlets run, too
Requires(post): systemd-units
Requires(preun): systemd-units
Requires(postun): systemd-units
# This is actually needed for the %%triggerun script but Requires(triggerun)
# is not valid. We can use %%post because this particular %%triggerun script
# should fire just after this package is installed.
Requires(post): systemd-sysv
# mysqlhotcopy needs DBI/DBD support
Requires: perl-DBI, perl-DBD-MySQL
Conflicts: MySQL-server
@ -189,6 +201,7 @@ the MySQL sources.
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
# workaround for upstream bug #56342
rm -f mysql-test/t/ssl_8k_key-master.opt
@ -330,12 +343,18 @@ chmod 755 ${RPM_BUILD_ROOT}%{_bindir}/mysql_config
mkdir -p $RPM_BUILD_ROOT/var/log
touch $RPM_BUILD_ROOT/var/log/mysqld.log
mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
mkdir -p $RPM_BUILD_ROOT/var/run/mysqld
install -m 0755 -d $RPM_BUILD_ROOT/var/lib/mysql
install -m 0755 %{SOURCE2} $RPM_BUILD_ROOT/etc/rc.d/init.d/mysqld
mkdir -p $RPM_BUILD_ROOT/etc
install -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/my.cnf
# install systemd unit files and scripts for handling server startup
mkdir -p ${RPM_BUILD_ROOT}%{_unitdir}
install -m 644 %{SOURCE11} ${RPM_BUILD_ROOT}%{_unitdir}/
install -m 755 %{SOURCE12} ${RPM_BUILD_ROOT}%{_libexecdir}/
install -m 755 %{SOURCE13} ${RPM_BUILD_ROOT}%{_libexecdir}/
mkdir -p $RPM_BUILD_ROOT/etc/tmpfiles.d
install -m 0644 %{SOURCE10} $RPM_BUILD_ROOT/etc/tmpfiles.d/mysql.conf
@ -408,15 +427,28 @@ rm -rf $RPM_BUILD_ROOT
%post server
if [ $1 = 1 ]; then
/sbin/chkconfig --add mysqld
# Initial installation
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
fi
/bin/chmod 0755 /var/lib/mysql
/bin/touch /var/log/mysqld.log
# Run this when upgrading from SysV initscript to native systemd unit
%triggerun server -- mysql-server < %{first_systemd_version}
# Save the current service runlevel info
# User must manually run systemd-sysv-convert --apply mysqld
# to migrate them to systemd targets
/usr/bin/systemd-sysv-convert --save mysqld >/dev/null 2>&1 || :
# Run these because the SysV package being removed won't do them
/sbin/chkconfig --del mysqld >/dev/null 2>&1 || :
/bin/systemctl try-restart mysqld.service >/dev/null 2>&1 || :
%preun server
if [ $1 = 0 ]; then
/sbin/service mysqld stop >/dev/null 2>&1
/sbin/chkconfig --del mysqld
# Package removal, not upgrade
/bin/systemctl --no-reload disable mysqld.service >/dev/null 2>&1 || :
/bin/systemctl stop mysqld.service >/dev/null 2>&1 || :
fi
%postun libs
@ -425,8 +457,10 @@ if [ $1 = 0 ] ; then
fi
%postun server
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
if [ $1 -ge 1 ]; then
/sbin/service mysqld condrestart >/dev/null 2>&1 || :
# Package upgrade, not uninstall
/bin/systemctl try-restart mysqld.service >/dev/null 2>&1 || :
fi
@ -572,7 +606,10 @@ fi
%{_datadir}/mysql/my-*.cnf
%{_datadir}/mysql/config.*.ini
/etc/rc.d/init.d/mysqld
%{_unitdir}/mysqld.service
%{_libexecdir}/mysqld-prepare-db-dir
%{_libexecdir}/mysqld-wait-ready
/etc/tmpfiles.d/mysql.conf
%attr(0755,mysql,mysql) %dir /var/run/mysqld
%attr(0755,mysql,mysql) %dir /var/lib/mysql
@ -611,6 +648,10 @@ fi
%{_mandir}/man1/mysql_client_test.1*
%changelog
* Wed Jul 27 2011 Tom Lane <tgl@redhat.com> 5.5.14-3
- Convert to systemd startup support (no socket activation, for now anyway)
Related: #714426
* Tue Jul 12 2011 Tom Lane <tgl@redhat.com> 5.5.14-2
- Remove make_scrambled_password and make_scrambled_password_323 from mysql.h,
since we're not allowing clients to call those functions anyway

51
mysqld-nowatch.patch Normal file
View File

@ -0,0 +1,51 @@
Add a --nowatch option to mysqld_safe that causes it to exit after
spawning mysqld. We don't need mysqld_safe to restart mysqld after
a crash, because systemd can do that just fine.
diff -Naur mysql-5.5.14.orig/scripts/mysqld_safe.sh mysql-5.5.14/scripts/mysqld_safe.sh
--- mysql-5.5.14.orig/scripts/mysqld_safe.sh 2011-06-21 12:42:40.000000000 -0400
+++ mysql-5.5.14/scripts/mysqld_safe.sh 2011-07-25 13:52:40.363068060 -0400
@@ -15,6 +15,7 @@
KILL_MYSQLD=1;
MYSQLD=
niceness=0
+nowatch=0
mysqld_ld_preload=
mysqld_ld_library_path=
@@ -54,6 +55,7 @@
--mysqld=FILE Use the specified file as mysqld
--mysqld-version=VERSION Use "mysqld-VERSION" as mysqld
--nice=NICE Set the scheduling priority of mysqld
+ --nowatch Exit after starting mysqld
--plugin-dir=DIR Plugins are under DIR or DIR/VERSION, if
VERSION is given
--skip-kill-mysqld Don't try to kill stray mysqld processes
@@ -140,8 +142,16 @@
;;
esac
- #echo "Running mysqld: [$cmd]"
- eval "$cmd"
+ if test $nowatch -eq 1
+ then
+ # We'd prefer to exec $cmd here, but SELinux needs to be fixed first
+ #/usr/bin/logger "Running mysqld: $cmd"
+ eval "$cmd &"
+ exit 0
+ else
+ #echo "Running mysqld: [$cmd]"
+ eval "$cmd"
+ fi
}
shell_quote_string() {
@@ -198,6 +208,7 @@
fi
;;
--nice=*) niceness="$val" ;;
+ --nowatch) nowatch=1 ;;
--open-files-limit=*) open_files="$val" ;;
--open_files_limit=*) open_files="$val" ;;
--skip-kill-mysqld*) KILL_MYSQLD=0 ;;

54
mysqld-prepare-db-dir Normal file
View File

@ -0,0 +1,54 @@
#!/bin/sh
# This script creates the mysql data directory during first service start.
# In subsequent starts, it does nothing much.
# extract value of a MySQL option from config files
# Usage: get_mysql_option SECTION VARNAME DEFAULT
# result is returned in $result
# We use my_print_defaults which prints all options from multiple files,
# with the more specific ones later; hence take the last match.
get_mysql_option(){
result=`/usr/bin/my_print_defaults "$1" | sed -n "s/^--$2=//p" | tail -n 1`
if [ -z "$result" ]; then
# not found, use default
result="$3"
fi
}
# Defaults here had better match what mysqld_safe will default to
get_mysql_option mysqld datadir "/var/lib/mysql"
datadir="$result"
get_mysql_option mysqld_safe log-error "/var/log/mysqld.log"
errlogfile="$result"
# Set up the errlogfile with appropriate permissions
touch "$errlogfile"
chown mysql:mysql "$errlogfile"
chmod 0640 "$errlogfile"
[ -x /sbin/restorecon ] && /sbin/restorecon "$errlogfile"
# Make the data directory
if [ ! -d "$datadir/mysql" ] ; then
# First, make sure $datadir is there with correct permissions
# (note: if it's not, and we're not root, this'll fail ...)
if [ ! -e "$datadir" -a ! -h "$datadir" ]
then
mkdir -p "$datadir" || exit 1
fi
chown mysql:mysql "$datadir"
chmod 0755 "$datadir"
[ -x /sbin/restorecon ] && /sbin/restorecon "$datadir"
# Now create the database
echo "Initializing MySQL database"
/usr/bin/mysql_install_db --datadir="$datadir" --user=mysql
ret=$?
chown -R mysql:mysql "$datadir"
if [ $ret -ne 0 ] ; then
exit $ret
fi
fi
exit 0

56
mysqld-wait-ready Normal file
View File

@ -0,0 +1,56 @@
#!/bin/sh
# This script waits for mysqld to be ready to accept connections
# (which can be many seconds or even minutes after launch, if there's
# a lot of crash-recovery work to do).
# Running this as ExecStartPost is useful so that services declared as
# "After mysqld" won't be started until the database is really ready.
# Service file passes us the daemon's PID
daemon_pid="$1"
# extract value of a MySQL option from config files
# Usage: get_mysql_option SECTION VARNAME DEFAULT
# result is returned in $result
# We use my_print_defaults which prints all options from multiple files,
# with the more specific ones later; hence take the last match.
get_mysql_option(){
result=`/usr/bin/my_print_defaults "$1" | sed -n "s/^--$2=//p" | tail -n 1`
if [ -z "$result" ]; then
# not found, use default
result="$3"
fi
}
# Defaults here had better match what mysqld_safe will default to
get_mysql_option mysqld datadir "/var/lib/mysql"
datadir="$result"
get_mysql_option mysqld socket "$datadir/mysql.sock"
socketfile="$result"
# Wait for the server to come up or for the mysqld process to disappear
ret=0
while /bin/true; do
RESPONSE=`/usr/bin/mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1`
mret=$?
if [ $mret -eq 0 ]; then
break
fi
# exit codes 1, 11 (EXIT_CANNOT_CONNECT_TO_SERVICE) are expected,
# anything else suggests a configuration error
if [ $mret -ne 1 -a $mret -ne 11 ]; then
ret=1
break
fi
# "Access denied" also means the server is alive
echo "$RESPONSE" | grep -q "Access denied for user" && break
# Check process still exists
if ! /bin/kill -0 $daemon_pid 2>/dev/null; then
ret=1
break
fi
sleep 1
done
exit $ret

24
mysqld.service Normal file
View File

@ -0,0 +1,24 @@
[Unit]
Description=MySQL database server
After=syslog.target
After=network.target
[Service]
Type=forking
User=mysql
Group=mysql
ExecStartPre=/usr/libexec/mysqld-prepare-db-dir
# Note: we set --basedir to prevent probes that might trigger SELinux alarms,
# per bug #547485
ExecStart=/usr/bin/mysqld_safe --nowatch --basedir=/usr
ExecStartPost=/usr/libexec/mysqld-wait-ready $MAINPID
# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300
# We rely on systemd, not mysqld_safe, to restart mysqld if it dies
Restart=always
[Install]
WantedBy=multi-user.target