MySQL Internals Support for Plug-Ins
← Back to MySQL Internals overview page
Contents |
[edit] Plugins
Beginning with MySQL 5.1, the server supports a plugin architecture for loading plugins. For example, several storage engines have been converted to plugins, and they can be selected or disabled at configuration time. You can build a plugin as static (compiled into the server) or dynamic (built as a dynamic library that must be installed using the INSTALL PLUGIN statement or the --plugin-load option before it can be used). Some plugins might not support static or dynamic build.
This section describes the command-line options that are used to control which plugins get built, and the CMake/autotools macros that enable plugin configuration support to be described. The support for building plugins is different in MySQL 5.5 and MySQL 5.1 (the build tools are CMake in 5.5, autotools in 5.1).
[edit] CMake Variables to Control Plugin Building (5.5 and Later)
- To build a plugin that is statically compiled into the server (assuming that the plugin supports static build), add -DWITH_<PLUGIN>=1 to the CMake command line.
- To exclude a plugin from the build, use -DWITHOUT_<PLUGIN>=1
- If neither WITH_<PLUGIN> nor WITHOUT_<PLUGIN> are defined, the plugin will be built as a shared module, if plugin supports it. If the plugin does not support build as a shared module, it won't be built.
- WITH_PLUGIN_<PLUGIN> and WITH_<PLUGIN>_STORAGE_ENGINE are also supported.
[edit] CMake Macro to Define the Plugin
To define a plugin, you need to add the MYSQL_ADD_PLUGIN() macro into CMakeList.txt. The syntax and examples are described here. Unlike in 5.1, there is no special plug.in script. If you need to perform system checks, use standard CMake techniques like CHECK_FUNCTION_EXISTS or CHECK_INCLUDE_FILE etc.
Note: There is NO autoheader-functionality. For example, CHECK_FUNCTION_EXISTS(epoll_wait HAVE_EPOLL_WAIT) will not automagically add "#define HAVE_EPOLL_WAIT 1" in config.h. Different plugins might chose different strategies to add plugin-specific defines
- Strategy 1 - use ADD_DEFINITIONS
This is similar to what InnoDB does in 5.5. An example
CHECK_FUNCTION_EXISTS(epoll_wait HAVE_EPOLL_WAIT) IF(HAVE_EPOLL_WAIT) ADD_DEFINITIONS(-DHAVE_EPOLL_WAIT=1) ENDIF()
- Strategy 2 - use own header template
It is more work than in Strategy 1 but result is a cleaner solution:
1) You need to have plugin specific <plugin>_config.h.in with content similar to
#cmakedefine HAVE_EPOLL_WAIT #cmakedefine HAVE_EPOLL_CTL
2) In CMakeLists.txt, add system checks
CHECK_FUNCTION_EXISTS(epoll_wait HAVE_EPOLL_WAIT) CHECK_FUNCTION_EXISTS(epoll_ctl HAVE_EPOLL_CTL)
After all system checks, add
CONFIGURE_FILE(plugin_config.h.in plugin_config.h)
3) use #include "plugin_config.h" in your source files
[edit] Autotools configure Support (MySQL 5.1)
Several configure options apply to plugin selection and building.
configure --help shows the following information pertaining to plugins:
- The plugin-related options
- The names of all available plugins
- For each plugin, a description of its purpose, which build types it supports (static or dynamic), and which plugin groups it is a part of.
The following configure options are used to select or disable plugins:
--with-plugins=PLUGIN[,PLUGIN]... --with-plugins=GROUP --with-plugin-PLUGIN --without-plugin-PLUGIN
PLUGIN is an individual plugin name such as csv or archive.
As shorthand, GROUP is a configuration group name such as none (select no plugins), all (select all plugins), or max (select all plugins used in a mysqld-max server).
--with-plugins can take a list of one or more plugin names separated by commas, or a plugin group name. The named plugins are configured to be built as static plugins.
--with-plugin-PLUGIN configures the given plugin to be built as a static plugin.
--without-plugin-PLUGIN disables the given plugin from being built.
If a plugin is named both with a --with and --without option, the result is undefined.
For any plugin that is not explicitly or implicitly (as a member of a selected group) selected or disabled, it is selected to be built dynamically if it supports dynamic build, and is disabled if it does not support dynamic build. If no plugin options are given, default group is selected.
[edit] Autotools Plugin Macros
The following macros enable plugin support in the autotools configuration files.
- Declaring a plugin:
MYSQL_PLUGIN(name,long-name,description[,configlist])
Each plugin is required to have MYSQL_PLUGIN() declared first. configlist is an optional argument that is a comma-separated list of configurations of which the module is a member.
Example:
MYSQL_PLUGIN(ftexample, [Simple Parser], [Simple full-text parser plugin])
- Declaring a storage engine plugin:
MYSQL_STORAGE_ENGINE(name,legacy-opt,long-name,description[,configlist])
This is a simple utility macro that calls MYSQL_PLUGIN. It performs the bare basics required to declare a storage engine plugin and provides support for handling the legacy configure command-line options. If legacy-opt is not specified, it will default to --with-name-storage-engine. Set the legacy-opt value to no if you do not want to handle any legacy option.
This macro is roughly equivalent to:
MYSQL_PLUGIN(name, 'long-name, description) MYSQL_PLUGIN_DEFINE(name, WITH_NAME_STORAGE_ENGINE)
Example:
MYSQL_STORAGE_ENGINE(berkeley, berkeley-db, [BerkeleyDB Storage Engine],
[Transactional Tables using BerkeleyDB], [max,max-no-ndb])
- Declaring a C preprocessor variable:
MYSQL_PLUGIN_DEFINE(name, define-name)
When a plugin will be included in a static build, this will set a preprocessor variable to 1. These preprocessor variables are defined in config.h.
Example:
MYSQL_PLUGIN_DEFINE(innobase, WITH_INNOBASE_STORAGE_ENGINE)
- Declaring a source directory for a plugin:
MYSQL_PLUGIN_DIRECTORY(name, dir-name)
Includes the specified directory into the build. If a file named configure is detected in the directory, it will be executed as part of the configure build otherwise it is assumed that there is a Makefile to be built in that directory. Currently, there is only support for plugin directories to be specified in the storage/ and plugin/ subdirectories.
Example:
MYSQL_PLUGIN_DIRECTORY(archive, [storage/archive])
- Declaring a static library name for a plugin:
MYSQL_PLUGIN_STATIC(name, dir-name)
Sets the configure substitution @plugin_name_static_target@ to the supplied library name if the plugin is a static build. It also adds the library to the list of libraries to be linked into mysqld. It may either be just the name of the library (where, if there is a directory specified, the directory will be prepended for the link) or another make variable or substitution (in which case, it will be passed through as is).
Example:
MYSQL_PLUGIN_STATIC(archive, [libarchive.a]) MYSQL_PLUGIN_STATIC(berkeley, [[\$(bdb_libs_with_path)]])
- Declaring a dynamic library name for a plugin:
MYSQL_PLUGIN_DYNAMIC(name, dso-name)
Sets the configure substitution @plugin_name_shared_target@ to the supplied dynamic shared object library name if the module is a dynamic build.
Example:
MYSQL_PLUGIN_DYNAMIC(archive, [ha_archive.la])
- Declaring a plugin as a mandatory module:
MYSQL_PLUGIN_MANDATORY(name)
Mandatory plugins cannot be disabled. Example:
MYSQL_PLUGIN_MANDATORY(myisam)
- Declaring a plugin as disabled:
MYSQL_PLUGIN_DISABLED(name)
A disabled plugin will not be included in any build. If the plugin has been marked as MANDATORY, it will result in an autoconf error.
- Declaring additional plugin configure actions:
MYSQL_PLUGIN_ACTIONS(name, configure-actions)
This is useful if there are additional configure actions required for a plugin. The configure-actions argument may either be the name of an autoconf macro or more autoconf script.
Example:
MYSQL_PLUGIN_ACTIONS(ndbcluster,[MYSQL_SETUP_NDBCLUSTER])
- Declaring plugin dependencies:
MYSQL_PLUGIN_DEPENDS(name, dependencies)
Declares all plugins, in a comma-separated list, that are required for the named plugin to be built. If the named plugin is selected, it will in turn enable all its dependencies. All plugins listed as a dependency must already have been declared with MYSQL_PLUGIN().
Example:
MYSQL_PLUGIN_DEPENDS(ndbcluster, [partition])
- Performing the magic:
MYSQL_CONFIGURE_PLUGINS(default-names)
Actually performs the task of generating the shell scripts for configure based upon the declarations made previously. It emits the shell code necessary to check the options and sets the variables accordingly. Example:
MYSQL_CONFIGURE_PLUGINS([none])
Plugin-related configure errors:
- When any plugin macro is called before
MYSQL_PLUGIN()is declared for that plugin, configure aborts with an error. - When any of the plugins specified in the dependency list don't exist, configure aborts with an error.
- When a mandatory plugin is specified in
--without-plugin-PLUGIN, configure aborts with an error. - When a disabled plugin is specified in
--with-modules=...or--with-plugin=PLUGIN, configure reports an error. - When an optional plugin that may only be built dynamically is specified in
--with-plugins=...or--with-plugin-PLUGIN, configure emits a warning and continues to configure the plugin for dynamic build. - When an optional plugin that may only be built statically is specified neither in
--with-plugins=...nor--without-plugin-PLUGIN, configure emits a warning but should proceed anyway.
Avoiding configure.in changes:
- If a plugin source (which is located in a subdirectory of the
storage/orplugin/directory) contains aplug.infile (for example,storage/example/plug.in), this file will be included as a part ofconfigure.in. This way,configure.indoes not need to be modified to add a new plugin to the build. - A
plug.infile may contain everything, particularly allMYSQL_PLUGIN_xxxmacros as just described. Theplug.infile does not need to specifyMYSQL_PLUGIN_DIRECTORY; it is set automatically to the directory of theplug.infile.
[edit] Specifying mysqld Variables Within a Plugin
A plugin can implement status and system variables. Information about this is in the plugin API section of the MySQL Reference Manual.
[edit] Additional Accessors for plugins
Starting with MySQL 5.1.21 the following additional accessors are made available to all plug-ins:
- Full definition of MYSQL_LEX_STRING (identical to LEX_STRING from m_string.h)
- Full definition of MYSQL_XID (binary compatible with XID from handler.h)
- mysql_tmpfile(), creates a temporary file in mysqld's tmpdir
- thd_killed(), to check killed state of connection
- thd_alloc() and similar allocation functions
- thd_get_xid(), to get XID of connection's transaction
- mysql_query_cache_invalidate4(), to invalidate a table's query cache entries
[edit] MySQL Services for Plugins
As of MySQL 5.5, plugins have access to server “services.” The services interface exposes server functionality that plugins can call. It complements the plugin API and has these characteristics:
- Services enable plugins to access code inside the server using ordinary function calls.
- Services are portable and work on multiple platforms.
- The interface includes a versioning mechanism so that plugin versions can be checked at load time against service versions supported by the server. Versioning protects against incompatibilities between the version of a service that the server provides and the version of the service expected or required by a plugin.
[edit] Plugin Services Components
On the plugin side of the services interface, the relevant information is provided in a set of header files. A plugin accesses this information by including the plugin.h file (which plugins must include anyway):
#include <mysql/plugin.h>
plugin.h includes the services.h file, which acts as an “umbrella” file that includes the service-specific headers with names of the form service_xxx.h. Within a MySQL source distribution, the header files are located in the include/mysql directory and have an inclusion hierarchy like this:
-
plugin.hincludesservices.h. -
services.his the “umbrella” header that includes all available service-specific header files. - Service-specific headers have names like
service_my_snprintf.horservice_thd_alloc.h.
The server side of the services interface uses the header files just listed, but also involves other files. Within a MySQL source distribution, these files are located in the libservices and sql directories:
The libservices directory contains the source files from which the libmysqlservices library is built. Files in this directory include:
-
HOWTO: Instructions for writing plugin services. -
xxx_services.h: Service-specific interface files.
Current service files are my_snprintf_service.c and thd_alloc_service.h.
During the MySQL build and install process, the libmysqlservices library is compiled and installed in a directory where plugins can access it. All plugins should link in this library using the -lmysqlservices flag when they are built.
The sql directory contains sql_plugin.cc, which implements plugin functionality. This file includes sql_plugin_services.h, where each available service is registered.
[edit] Writing Services for Use from Within Plugins
Services are implemented by modifying server code in the sql directory to register the service in the plugin code, and by providing interface files in the libservices directory and under the include directory.
For complete instructions on writing a service, see the HOWTO file in the libservices directory within a MySQL source distribution. As you read the HOWTO file, you might find it useful to examine the files that implement existing services.
When you write a service, be sure to provide complete instructions on how to use it. A service named xxx will have a file named service_xxx.h in the include/mysql directory. For the benefit of plugin developers who use your service, this file should include comments that fully document the service interface:
- Its purpose
- Any applicable guidelines, including limitations or restrictions
- For each function, a description of what it does, its calling sequence, and return value
The goal for documentation in this file is that plugin developers should be able to look at the file and completely understand how to use the service.