On MySQL plugin configuration

MySQL offers plugin API, with which you can add different types of plugins to the server. The API is roughly the same for all plugin types: you implement an init() function, a deinit(); you declare status variables and global variables associated with your plugin, and of course you implement the particular implementation of plugin call.

I wish to discuss the creation and use of global variables for plugins.

Consider the following declaration of a global variable in audit_login:

static MYSQL_SYSVAR_BOOL(enabled, plugin_enabled, PLUGIN_VAR_NOCMDARG,
"enable/disable the plugin's operation, namely writing to file", NULL, NULL, 1);

static struct st_mysql_sys_var * audit_login_sysvars[] = {
    MYSQL_SYSVAR(enabled),
    NULL
};

The above creates a new global variables called “simple_login_audit_enabled”: it is composed of the plugin name (known to be “simple_login_audit” in our example) and declared name (“enabled”). It is a boolean, defaults to 1, and is associated with the internal plugin_enabled variable.

Once this variable is declared, you can expect to be able to:

mysql> show global variables like '%audit%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| simple_login_audit_enabled | ON    |
+----------------------------+-------+

mysql> set global simple_login_audit_enabled := 0;
Query OK, 0 rows affected (0.00 sec)

and you can expect using the following in your my.cnf file:

[mysqld]
...
simple_login_audit_enabled=1

Assuming your server agrees to start

Here’s the catch: the simple_login_audit_enabled variable is only recognized as long as the plugin is installed. As you may know, plugins can be loaded upon startup time using an explicit my.cnf entry such as:

plugin_load=audit_login.so

But you may also, at any given time, INSTALL or UNINSTALL the plugin dynamically.

install plugin SIMPLE_LOGIN_AUDIT soname 'audit_login.so';
uninstall plugin SIMPLE_LOGIN_AUDIT;

In fact there are good reasons to do so: you may be upgrading your plugin. You can’t just throw in the new binary (it’s a guaranteed crash on next server shutdown). You need to first UNINSTALL it; you then put the new binary, and re-INSTALL. This works well, and the price is some downtime for your plugin.

But what happens if you restart the server while your plugin is uninstalled? Yep: the global variable is unrecognised, and your MySQL server refuses to start:

130919  8:11:30 [ERROR] /usr/bin/mysqld: unknown variable 'simple_login_audit_enabled=1'
130919  8:11:30 [ERROR] Aborting
130919  8:11:30  InnoDB: Starting shutdown...
130919  8:11:31  InnoDB: Shutdown completed; log sequence number 40185651
130919  8:11:31 [Note] /usr/bin/mysqld: Shutdown complete

I did happen on this case a couple times; it is frustrating.

What are the alternatives?

So adding variables to my.cnf may prevent MySQL from starting. In my dictionary, this spells “NO GO”.

With audit_login I chose to (additionally) support an external config file, audit_login.cnf, expected to be found in the @@datadir. It is similar in essence to the master.info file which is expected by replication. The plugin reads this file (if existing) upon init(), which makes it execute upon server startup or upon INSTALL PLUGIN. I can’t argue that this is the best solution, but it is a solution that does not interfere with anyone. The file is ignored by all and does not disturb the public peace. The plugin does not require it to exist.

I was hoping to be able to directly read from my.cnf, but am unsure if there is a definitive way to do so from within the plugin. I did not go deep into this.

What would be best?

Hopefully I’m not missing on anything. But it would be nice to have plugin-dedicated variables in my.cnf which are ignored by the server. These could take the form of:

[mysql_plugin]
simple_login_audit_enabled=0

or similar. It would be the server’s responsibility to pass these declarations to the plugins, but ignore them itself (or just pass warning).

9 thoughts on “On MySQL plugin configuration

  1. @Daniël,

    You don’t get SQL access from within your plugin, so reading from a table is not a trivial thing. I’m actually unsure how you can get any SQL access.

  2. You could setup a client and connect via outside, but that’s not a clean solution.
    How does the InnoDB/NDB memcached plugin access data? It does use config in a table.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.