MySQL 5.7 — Native Systemd Support


Systemd is a management and configuration platform available in all major Linux distributions. It provides infrastructure for service start, stop, restart and several other novel functionalities to manage services. Systemd replaces SysV and upstart initialization systems and is the default init system in most modern Linux distributions including Red Hat Enterprise Linux, Oracle Linux, Debian, Ubuntu, Fedora, SLES and openSUSE.

Preliminary support for systemd was introduced in earlier versions of MySQL. However, it had the following limitations and disadvantages:

  1. Use of ping tricks to check whether mysqld is ready to serve client connections.
  2. Though systemd had superior process control for automatic restarts, mysqld_safe was still used to identify abnormal mysqld termination and do automatic restarts.
  3. There was no auto-detection of systemd configuration paths to generate service unit files for various distributions.
  4. There was no integration with our CMake build system.

To overcome the above limitations and disadvantages, some minimal support should be provided within the server. With the release of MySQL 5.7.6, these limitations have been overcome and complete support for systemd is added on systemd based platforms Red Hat Enterprise Linux 7, Oracle Linux 7, CentOS 7, SLES 12, Fedora 20 & Fedora 21. Thus, MySQL 5.7.6 provides full native support for systemd, thereby leveraging the latest functionalities of all the major Linux distributions to their fullest capacity.

Command-line Option to Start mysqld in Daemon Mode

A new command-line option –-daemonize has been added which when enabled does a SysV style daemon initialization. This enables us to use a forking type service unit file for mysqld. Earlier on, we were using the simple type unit file for mysqld. This had the disadvantage that the mysqld service was had a state=running before the server was actually ready to handle client connections. This could cause problems by denying client connections from follow-up services that depend on the mysqld service. Also in some cases the server undergoes crash recovery—for which the completion time can vary wildly from sub-second times to many minutes—before the server is actually ready to handle connections. This resulted in the client connections of follow-up units to timeout and report failures.

With the forking type server (which uses the –-daemonize option), the disadvantage of using ping tricks to identify that mysqld is able to begin serving client connections is overcome. When mysqld is invoked with –-daemonize option, the parent process does a double fork and the grand child sets up the pid file and the listen socket initialization among other initialization steps. The grand child then notifies the parent to exit and this notifies systemd to set the service state to “running”.

Start, Stop, Restart and Status Functionality

We can now start, stop, restart and manage other functionalities of the MySQL server using systemd. Installing the rpm package for MySQL server will automatically enable the mysqld service. The systemctl command is the primary interface to control, query, and manage the functionality provided by systemd. After installing the MySQL server package, you can check to see whether mysqld is enabled or not, this way:

$ systemctl is-enabled mysqld

This means that mysqld is automatically started at boot time or when you start the mysqld service after package install. The appropriate data directory creation and initialization is automatically taken care of as well.

We can start the mysqld service using:

$ systemctl start mysqld

We can see the status of mysqld with:

$ systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
   Active: active (running) since Mon 2015-04-06 06:56:56 BST; 13min ago
  Process: 1030 ExecStart=/usr/sbin/mysqld --daemonize $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 957 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 1071 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─1071 /usr/sbin/mysqld --daemonize

We can restart mysqld with:

$ systemctl restart mysqld

We can stop mysqld with:

$ systemctl stop mysqld

Automatic Restarts

One of the major pieces of functionality offered by systemd is integrated process monitoring and automatic restarts in the event of a service failure/termination. Starting with MySQL 5.7.6, process monitoring and auto-restarts are now handled by systemd on systems that have it. If mysqld fails due to a restartable failure like a crash, then systemd automatically restarts mysqld. As an example, this can be verified by:

$ systemctl start mysqld
$ systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
   Active: active (running) since Mon 2015-04-06 07:18:51 BST; 11s ago
  Process: 3010 ExecStart=/usr/sbin/mysqld --daemonize $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 2994 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 3014 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─3014 /usr/sbin/mysqld --daemonize
$ kill -SEGV 3014
$ systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
   Active: active (running) since Mon 2015-04-06 07:19:53 BST; 2s ago
  Process: 3057 ExecStart=/usr/sbin/mysqld --daemonize $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 3042 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 3061 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─3061 /usr/sbin/mysqld --daemonize

Passing Custom Options to mysqld

mysqld_safe has a --malloc-lib option which allows you to specify a non-default library (e.g. jemalloc). mysqld_safe then sets the LD_PRELOAD environment variable and starts mysqld under this environment setting. On systemd based machines, the mysqld service unit file has the EnvironmentFile key set to /etc/sysconfig/mysql. You can then use an alternative malloc library by adding an entry in the /etc/sysconfig/mysqld file like this:

$ echo "LD_PRELOAD=/path/of/malloc/" >> /etc/sysconfig/mysqld

You can also pass other custom options to mysqld by creating additional entries/lines in /etc/sysconfig/mysql using the MYSQLD_OPTS=”option” format. Lastly, you can also specify custom options and environment variables using the systemctl command:

$ systemctl set-environment MYSQLD_OPTS="--general_log=1"

The custom options can also be unset using:

$ systemctl unset-environment MYSQLD_OPTS

You must then restart the mysqld service for the new environment or configuration settings to take effect.

Systemd Service and Support Files

Two systemd service configuration files and one support file are shipped with MySQL 5.7.6 in order to enable support for systemd:

  1. mysqld.service: This is the systemd service definition file that tells it what service to start, specifies auto-restart settings, the type of service it is and all of the dependencies between various units, etc. Here is the content of the mysqld.service file that is now installed in /usr/lib/systemd/system on Fedora 21:
    Description=MySQL Server
    # Execute pre and post scripts as root
    # Needed to create system tables
    # Start main service
    ExecStart=/usr/sbin/mysqld --daemonize $MYSQLD_OPTS
    # Use this to switch malloc implementation
  2. mysql.conf: This file describes configuration settings like the location of tmp files, permission mode and ownership, the age of tmpfiles that relate to mysqld service, and so on. For example, this file is installed in /usr/lib/tmpfiles.d on Fedora 21 with these contents:
    d /var/run/mysqld 0755 mysql mysql -
  3. mysqld_pre_systemd: This is a bash script file that generates the data directory when mysqld is started for the first time via systemctl. This script is run by systemd before starting mysqld in order to check for the presence of a proper data/mysql directory within the data directory location specified. If the data/mysql directory doesn’t exist, then systemd runs mysqld with the --initialize option to create the data directory (this files is typically installed in /usr/bin). For more information on the new bootstrap process in MySQL 5.7, please see Joro’s blog post.


MySQL 5.7.6 brings complete systemd support and is the first among the many variants of MySQL available in the marketplace to support systemd natively. We hope that you enjoy managing MySQL under systemd!

We also look forward to your feedback on this new work!. You can leave a comment here on the blog post or in a support ticket. If you feel that you encountered any related bugs, please do let us know via a bug report. Also you can find more details about managing MySQL 5.7.6 using systemd and the systemd related build options in the MySQL 5.7 docs here.

As always, THANK YOU for using MySQL!

13 thoughts on “MySQL 5.7 — Native Systemd Support

  1. First: thanks for improving the situation – the previous “mysqladmin ping” hacks were rather unfortunate.

    Could you shed some light on why you implemented it as “forking”, using a PIDFile for process tracking instead of simply running it as Type=”notify” and using sd_notify() to inform systemd about the service availability?

    When running it forking, the direct process control is lost and systemd needs to keep track in a hackish way by reading the PIDFile, looking for the associated processed and checking their status.

    When using Type=”notify”, no forking would be necessary and the service would just have to call sd_notify() once it considers itself to be up and running.
    Besides that, the process tracking/control for systemd is way more straightforward, as it doesn’t has to hunt the service’s processes but just uses the still attached/non-forked process as entry point instead.

    1. Hello Eliasp,
      Thank you for your valuable comments and suggestions. We have decided not to use the Type=notify feature
      of systemd because it involves linking our code with the and use the headers and
      calling a special function sd_notify to indicate readiness. We have some licensing issues given
      libsystemd-daemon is LGPL and apart from that this is some sort of dependency on systmed to use init services.
      It would be great if systemd provides some sort of generic readiness protocol without linking to their
      library and calling and using their special functions.
      Thayumanavar S.

      1. Well, systemd does provide a generic protocol and you don’t really need sd_notify – they are just convenience helper functions.

        The protocol itself is really trivial: the environment variable NOTIFY_SOCKET contains the path to a UNIX domain socket that is to be used for readiness notifications (if the value starts with an ‘@’, it’s an abstract socket), and if you want to notify systemd of anything, you just send a datagram to that socket. This can easily be done manually, you don’t need to link to anything related to systemd here.

        I’ve written the following code without looking at libsystemd-daemon, by just putting together the required system calls to achieve this:

        Consider the code in the pastebin public domain – but I doubt that anyone would come up with something substantially different given the description of the protocol.

        1. Hello Christian!,
          Thank you for the comments and details.
          It appears that the readiness protocol is documented only as part of sd_notify man page. Please let me know if whether this readiness protocol is documented as part of systemd spec. and will be adhered by client implementations. Our main concern is the we need to support different types of distributions like RHEL, SLES, Ubuntu etc. This distribution may likely modify the sd_notify implementation and systemd to suit their needs by having different protocol and we would break implementing the protocol that is documented as part of man page of sd_notify for that particular distribution. When we set out our main goal is to remove the ping hacks that mysqld_safe script was doing. We have achieved this using the forking type at the same time maintaining the portability and maintenance concerns that notify type lends to. We thank for your valuable feedback and suggestions and we will carefully evaluate using the notify type of systemd to leverage the additional functional features in future and in line with our requirements.

          1. (Sorry for replying so late.)

            When it comes to stability, there are two things:

            There’s the systemd interface stability promise, which promises that among the interfaces that are considered stable there is: The protocol spoken on the socket referred to by $NOTIFY_SOCKET, as documented in sd_notify(3).

            Furthermore, there are implementations of the protocol natively in other languages (for example Go) that don’t use the C bindings.

            If somebody decided to change the protocol, this would therefore cause all kinds of software to break. I also don’t see distributions modifying that in any way for that reason – especially since it’s part of the interface stability promise, and it’s also mentioned on the interface portability chart, where it says “yes” to “reimplementable independently”.

            Also, consider that the protocol is extensible: you send newline-separated Key-Value pairs over that protocol, “READY=1” is just the simplest thing you can send – and it has already been extended in the past (e.g. watchdog functionality) without breaking previous users.

            As for documentation: sd_notify(3) is the only one I know of – on the other hand, I don’t how much more detail you can add to the statement “send a bunch of newline-separated key-value-pairs to a SOCK_DGRAM AF_UNIX socket given by $NOTIFY_SOCKET, and here’s a list of possible keys with their semantics” without already providing an implementation. (And note that if you use sd_notify(3), you still have to specify the keys yourself, so that part of the protocol has to be stable even if you use sd_notify, the only part that sd_notify really does is that it provides a nice wrapper around the socket system calls.)

  2. > provides full native support for systemd

    That’s still not true. Your workaround indeed become way less ugly than before but it’s still far away from “native”. The right way to go would be to implement socket activation in mysql: this way you don’t have to bother with forking or notification protocol – let systemd listen to socket and just receive pre-opened fd from it.

    This would also greatly improve upgrading – no client connection is lost upon restart.

  3. Hello! I have a problem with managing multiple instance of MySql 7.7.11. I am trying start second unit as well as the first, but but it does not work with Type=forking – first instance starts as well, butt second tries write to datadir of first instance:
    InnoDB: Unable to lock ./ibdata1 error: 11

    Options in unit file and my.cnf (both) sets ok. When i delete option Type, and remove “–daemonize” from ExecStart, all is well.

    What may be wrong?

    Sorry for my English.

Leave a Reply