10.5: Control MySQL server with launchd

Feb 05, '08 07:30:02AM

Contributed by: mmnw

I recently installed a copy of the MySQL database server on my Leopard machine. The MySQL site offers a packaged version of MySQL 5.0.x for OS X 10.4 on their downloads page (current as of this posting: 5.0.51).

This 10.4 version works perfectly well with 10.5, except for some minor inconveniences. The first is that they include a preference pane for System Preferences, which doesn't work. They also offer to install a StartupItem to start the database server during boot. This works pretty well, except that Apple has marked StartupItems as depreciated since 10.4, noting that you should use launchd instead. There are many hints out there to create a launchd job using the MySQL supplied launchd_safe, which is basically a shell script for starting, monitoring, and restarting mysqld. That's a pretty ugly solution to start a server with launchd, and is actually discouraged by Apple.

So this hint is about replacing the StartupItem and the mysqld_safe script with a simple launchd job. It assumes you are familiar with the Terminal, logged with an administrator account, and have basic knowledge of launchctl and launchd.plist files. Also being familiar with MySQL configuration might help.

Here's how to set it up:

  1. Install the latest copy of mySQL (if not already installed) using the links above. This will place a copy of mysql in /usr/local/mysql-version#, and create a link at /usr/local/mysql. It might offer to install the mentioned StartupItem; do not do this. If you already have this StartupItem, remove it (it's located in /Library/StartupItems).
  2. Create the following plist file in your favorite text editor, or use the Property List Editor which comes with XCode, and save it as com.mysql.mysqld.plist:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Disabled</key>
        <false/>
        <key>GroupName</key>
        <string>_mysql</string>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>
        <string>com.mysql.mysqld</string>
        <key>Program</key>
        <string>/usr/local/mysql/bin/mysqld</string>
        <key>ProgramArguments</key>
        <array>
            <string>--user=_mysql</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>Umask</key>
        <integer>7</integer>
        <key>UserName</key>
        <string>_mysql</string>
        <key>WorkingDirectory</key>
        <string>/usr/local/mysql</string>
    </dict>
    </plist>
  3. Copy (or move) this file to /Library/LaunchDaemons, and then change ownership and permissions in Terminal (supply your login password when asked):
    $ cd /Library/LaunchDaemons
    $ sudo chown root com.mysql.mysqld
    $ sudo chgrp wheel com.mysql.mysqld
    $ sudo chmod 644 com.mysql.mysqld
  4. Afterwards, submit the job to launchd by typing sudo launchctl load com.mysql.mysqld.plist. The server should start immediately. If not, check with Console.app for error messages from launchd with the tag com.mysql.mysqld.
This example implements just a simple mysql daemon install. You can modify the plist file to suit your needs. If you edit the file after you submitted it to launchd via launchctl load, you should always remember to first execute a launchctl unload com.mysql.mysqld.plist, check for user, group, and permissions, and then resubmit via launchctl load as in steps three and four above.

You can add various command-line options to mysqld if you like (check the MySQL documentation for all the options). In its default configuration, mysqld will also read the /etc/my.cnf file during startup, but if you are like me and have all configuration in one place, you can add them right here in the launchd.plist. There are command line options for all my.cnf parameters. As an example, I added the following to the ProgramArguments array, since I like to keep my database in the Library folder (whereas the default would be /usr/local/mysql/data):
<string>--datadir=/Library/mySQL/data</string>
<string>--pid-file=/Library/mySQL/data/iMac.local.pid</string>
You could also add something like the following to get specific log and error information (if you don't add these, they won't be lost; they end up in the general log in Console.app):
<key>StandardErrorPath</key>
<string>/var/log/mysqlerr.log</string>
<key>StandardOutPath</key>
<string>/var/log/mysqlout.log</string>
The provided launchd example also implements an always-running daemon (via RunAtLoad and KeepAlive), which starts at boot and never quits (and if it does, launchd restarts it). It should be possible to implement an "on demand server" by implementing a Sockets section in the plist file, but I haven't tried this (read man launchd.plist for details, or have a look the various plist files in /System/Library/LaunchDaemons).

Comments (18)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20080128103022907