I've got mysql running with a systemd service file on my machine. As was suggested earlier in the bug report, I started with the fedora scripts so there may be some fedoraisms to check on. The only problem I had just using them was an issue with mysql-wait-ready where the ping line was improperly formated resulting in usage info getting printed out. As you can see, I added a little bit of extra output around that section to help debug. Since /usr/bin/mysqld_safe sources /etc/mysql/debian.cnf and systemd runs everything as the mysql user, I also had to chgrp mysql /etc/mysql/debian.cnf; chmod g+r /etc/mysql/debian.cnf.
####################### mysql.service # For more info about custom unit files, see systemd.unit(5) or # http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F # For example, if you want to increase mysql's open-files-limit to 10000, # you need to increase systemd's LimitNOFILE setting, so create a file named # "/etc/systemd/system/mariadb.service.d/limits.conf" containing: # [Service] # LimitNOFILE=10000 [Unit] Description=MySQL database server After=syslog.target network.target [Service] Type=simple User=mysql Group=mysql ExecStartPre=/usr/bin/mysql-prepare-db-dir %n # Note: we set --basedir to prevent probes that might trigger SELinux alarms, # per bug #547485 ExecStart=/usr/bin/mysqld_safe --basedir=/usr ExecStartPost=/usr/bin/mysql-wait-ready $MAINPID # Give a reasonable amount of time for the server to start up/shut down TimeoutSec=300 # Security PrivateTmp=yes #InaccessibleDirectories=/boot /.config /home/backups /home/bill /home/sleeper /lib32 /media /mnt /opt /proc /root /srv /sys #ReadOnlyDirectories=/bin /etc /sbin /usr #CapabilityBoundingSet=~CAP_SYS_PTRACE #DeviceAllow=/dev/null rw #NoNewPrivileges=yes [Install] WantedBy=multi-user.target ####################### /usr/bin/mysql-prepare-db-dir #!/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/mysql/error.log" errlogfile="$result" get_mysql_option mysqld socket "$datadir/mysql.sock" socketfile="$result" # Absorb configuration settings from the specified systemd service file, # or the default "mysqld" service if not specified SERVICE_NAME="$1" if [ x"$SERVICE_NAME" = x ] then SERVICE_NAME=mysqld.service fi myuser=`systemctl show -p User "${SERVICE_NAME}" | sed 's/^User=//'` if [ x"$myuser" = x ] then myuser=mysql fi mygroup=`systemctl show -p Group "${SERVICE_NAME}" | sed 's/^Group=//'` if [ x"$mygroup" = x ] then mygroup=mysql fi # Set up the errlogfile with appropriate permissions touch "$errlogfile" chown "$myuser:$mygroup" "$errlogfile" chmod 0640 "$errlogfile" #[ -x /sbin/restorecon ] && /sbin/restorecon "$errlogfile" # We check if there is already a process using the socket file, # since otherwise this systemd service file could report false # positive result when starting and mysqld_safe could remove # a socket file, which actually uses a different daemon. if fuser "$socketfile" > /dev/null ; then echo "Socket file $socketfile exists." >&2 echo "Is another MySQL daemon already running with the same unix socket?" >&2 exit 1 fi # 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 "$myuser:$mygroup" "$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="$myuser" ret=$? if [ $ret -ne 0 ] ; then echo "Initialization of MySQL database failed." >&2 echo "Perhaps /etc/my.cnf is misconfigured." >&2 # Clean up any partially-created database files if [ ! -e "$datadir/mysql/user.frm" ] ; then rm -rf "$datadir"/* fi exit $ret fi # In case we're running as root, make sure files are owned properly chown -R "$myuser:$mygroup" "$datadir" fi exit 0 ####################### /usr/bin/mysql-wait-ready #!/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 (actually, mysqld_safe'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 "/var/lib/mysql/mysql.sock" socketfile="$result" # Wait for the server to come up or for the mysqld process to disappear ret=0 while /bin/true; do MYSQLDRUNNING=0 if [ -d "/proc/${daemon_pid}" ] ; then MYSQLDRUNNING=1 fi RESPONSE=`/usr/bin/mysqladmin --no-defaults --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1` mret=$? if [ $mret -eq 0 ] && [ $MYSQLDRUNNING -eq 1 ]; 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 "Received bad response from mysql..." echo "$RESPONSE" echo "$mret" 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 echo "Process does not exist" ret=1 break fi sleep 1 done exit $ret