Using the Embedded Server Library

MySQL 4 introduces an embedded server library, libmysqld, that contains the server in a form that can be linked (embedded) into applications. This allows you to produce MySQL-based applications that stand on their own, as opposed to applications that connect as a client over a network to a separate server program.

To write an embedded server application, two requirements must be satisfied. First, the embedded server library must be installed:

  • If you're building from source, enable the library by using the --with-embedded-server option when you run configure.

  • For binary distributions, use a Max distribution if the non-Max distribution doesn't include libmysqld.

  • For RPM installs, make sure to install the embedded server RPM.

Second, you'll need to include a small amount of code in your application to start up and shut down the server.

After making sure that both requirements are met, it's necessary only to compile the application and link in the embedded server library (-lmysqld) rather than the regular client library (-lmysqlclient). In fact, the design of the server library is such that if you write an application to use it, you can easily produce either an embedded or a client/server version of the application simply by linking in the appropriate library. This works because the regular client library contains interface functions that have the same calling sequence as the embedded server calls but are stubs (dummy routines) that do nothing.

Writing an Embedded Server Application

Writing an application that uses the embedded server is little different than writing one that operates in a client/server context. In fact, if you begin with a program that is written as a client/server application, you can convert it easily to use the embedded server instead. For example, to modify client4 to produce an embedded application named embapp, copy client4.c to embapp.c and then perform the following steps to modify embapp.c:

  1. Add mysql_embed.h to the set of MySQL header files used by the program:

    #include <my_global.h> 
    #include <mysql.h>
    #include <mysql_embed.h>
    #include <my_getopt.h>
  2. An embedded application includes both a client side and a server side, so it can process one group of options for the client and another group for the server. For example, an application named embapp might read the [client] and [embapp] groups from option files for the client part. To set that up, modify the definition of the client_groups array to look like this:

    static const char *client_groups[] = 
        "client", "embapp", NULL

    Options in these groups can be processed by load_defaults() and handle_options() in the usual fashion. Then define another list of option groups for the server side to use. By convention, this list should include the [server] and [embedded] groups and also the [appname_SERVER] group, where appname is the name of your application. For a program named embapp, the application-specific group will be [embapp_SERVER], so you declare the list of group names as follows:

    static const char *server_groups[] = 
        "server", "embedded", "embapp_SERVER", NULL
  3. Call mysql_server_init() before initiating communication with the server. A good place to do this is before you call mysql_init().

  4. Call mysql_server_end() after you're done using the server. A good place to do this is after you call mysql_close().

After making these changes, the main() function in embapp.c will look like this:

main (int argc, char *argv[])
int opt_err;

    my_init ();
    load_defaults ("my", client_groups, &argc, &argv);

    if ((opt_err = handle_options (&argc, &argv, my_opts, get_one_option)))
        exit (opt_err);

    /* solicit password if necessary */
    if (ask_password)
        opt_password = get_tty_password (NULL);

    /* get database name if present on command line */
    if (argc > 0)
        opt_db_name = argv[0];
        --argc; ++argv;

    /* initialize embedded server */
    mysql_server_init (0, NULL, (char **) server_groups);

    /* initialize connection handler */
    conn = mysql_init (NULL);
    if (conn == NULL)
        print_error (NULL, "mysql_init() failed (probably out of memory)");
        exit (1);

    /* connect to server */
    if (mysql_real_connect (conn, opt_host_name, opt_user_name, opt_password,
            opt_db_name, opt_port_num, opt_socket_name, opt_flags) == NULL)
        print_error (conn, "mysql_real_connect() failed");
        mysql_close (conn);
        exit (1);

    while (1)
        char    buf[10000];

        fprintf (stderr, "query> ");                    /* print prompt */
        if (fgets (buf, sizeof (buf), stdin) == NULL)   /* read query */
        if (strcmp (buf, "quit\n") == 0 || strcmp (buf, "\\q\n") == 0)
        process_query (conn, buf);                      /* execute query */

    /* disconnect from server */
    mysql_close (conn);
    /* shut down embedded server */
    mysql_server_end ();
    exit (0);

Producing the Application Executable Binary

To produce the embedded-server executable binary for embapp, link in the -lmysqld library rather than the -lmysqlclient library. The mysql_config utility is useful here. Just as it can show you the flags to use for linking in the regular client library, it also can display the flags necessary for the embedded server:

% mysql_config --libmysqld-libs 
 -L'/usr/local/mysql/lib/mysql' -lmysqld -lz -lm

Thus, to produce an embedded version of embapp, use commands such as these:

% gcc -c `mysql_config --cflags` embapp.c 
% gcc -o embapp embapp.o `mysql_config --libmysqld-libs`

At this point, you have an embedded application that contains everything you need to access your MySQL databases. However, be sure when you execute embapp that it does not attempt to use the same data directory as any standalone servers that may already be running on the same machine. Also, under UNIX, the application must run with privileges that give it access to the data directory. You can either run embapp while logged in as the user that owns the data directory, or you can make it a setuid program that changes its user ID to that user when it starts up. For example, to set embapp to run with the privileges of a user named mysqladm, issue the following commands as root:

# chown mysqladm embapp 
# chmod 4755 embapp

Should you decide that you want to produce a non-embedded version of the application that operates in a client/server context, link it against the regular client library. You can do so by building it as follows:

% gcc -c `mysql_config --cflags` embapp.c 
% gcc -o embapp embapp.o `mysql_config --libs`

The regular client library includes dummy versions of mysql_server_init() and mysql_server_end() that do nothing, so no link errors will occur.