[mysql] Convert to systemd startup support
Tom Lane
tgl at fedoraproject.org
Wed Jul 27 19:14:17 UTC 2011
commit 69a13754993137c004c4c59c5e4bd85e4b5ab791
Author: Tom Lane <tgl at redhat.com>
Date: Wed Jul 27 15:13:15 2011 -0400
Convert to systemd startup support
mysql.init | 228 -------------------------------------------------
mysql.spec | 67 ++++++++++++---
mysqld-nowatch.patch | 51 +++++++++++
mysqld-prepare-db-dir | 54 ++++++++++++
mysqld-wait-ready | 56 ++++++++++++
mysqld.service | 24 +++++
6 files changed, 239 insertions(+), 241 deletions(-)
---
diff --git a/mysql.spec b/mysql.spec
index 0594a36..adfb127 100644
--- a/mysql.spec
+++ b/mysql.spec
@@ -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 at 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 at 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
diff --git a/mysqld-nowatch.patch b/mysqld-nowatch.patch
new file mode 100644
index 0000000..9ca2d12
--- /dev/null
+++ b/mysqld-nowatch.patch
@@ -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 ;;
diff --git a/mysqld-prepare-db-dir b/mysqld-prepare-db-dir
new file mode 100644
index 0000000..72badd7
--- /dev/null
+++ b/mysqld-prepare-db-dir
@@ -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
diff --git a/mysqld-wait-ready b/mysqld-wait-ready
new file mode 100644
index 0000000..10e86fe
--- /dev/null
+++ b/mysqld-wait-ready
@@ -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
diff --git a/mysqld.service b/mysqld.service
new file mode 100644
index 0000000..b3bc486
--- /dev/null
+++ b/mysqld.service
@@ -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
More information about the scm-commits
mailing list