每个包含服务器插件的插件库都必须包含一个库描述符,该描述符包含文件中每个服务器插件的通用插件描述符。本节讨论如何为服务器插件编写库和通用描述符。
库描述符必须定义两个符号
_mysql_plugin_interface_version_
指定通用插件框架的版本号。这由MYSQL_PLUGIN_INTERFACE_VERSION
符号给出,该符号在plugin.h
文件中定义。_mysql_plugin_declarations_
定义一个插件声明数组,以所有成员都设置为 0 的声明结束。每个声明都是st_mysql_plugin
结构的实例(也在plugin.h
中定义)。库中的每个服务器插件都必须有一个。
如果服务器在库中找不到这两个符号,它不会将其接受为合法插件库,并会以错误拒绝它。这可以防止在非专门构建为插件库的情况下使用库。
定义这两个必需符号的传统方法是使用来自 plugin.h
文件的 mysql_declare_plugin()
和 mysql_declare_plugin_end
宏
mysql_declare_plugin(name)
... one or more server plugin descriptors here ...
mysql_declare_plugin_end;
每个服务器插件都必须有一个通用描述符,为服务器插件 API 提供信息。所有插件类型的通用描述符具有相同的结构。 plugin.h
文件中的 st_mysql_plugin
结构定义了此描述符
struct st_mysql_plugin
{
int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
void *info; /* pointer to type-specific plugin descriptor */
const char *name; /* plugin name */
const char *author; /* plugin author (for I_S.PLUGINS) */
const char *descr; /* general descriptive text (for I_S.PLUGINS) */
int license; /* the plugin license (PLUGIN_LICENSE_XXX) */
int (*init)(void *); /* the function to invoke when plugin is loaded */
int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
unsigned int version; /* plugin version (for I_S.PLUGINS) */
struct st_mysql_show_var *status_vars;
struct st_mysql_sys_var **system_vars;
void * __reserved1; /* reserved for dependency checking */
unsigned long flags; /* flags for plugin */
};
st_mysql_plugin
描述符结构成员的使用方式如下。 char *
成员应指定为以 null 结尾的字符串。
-
type
: 插件类型。这必须是plugin.h
中的某个插件类型值/* The allowable types of plugins */ #define MYSQL_UDF_PLUGIN 0 /* User-defined function */ #define MYSQL_STORAGE_ENGINE_PLUGIN 1 /* Storage Engine */ #define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */ #define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */ #define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */ #define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */ #define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */ #define MYSQL_AUTHENTICATION_PLUGIN 7 /* The authentication plugin type */ #define MYSQL_VALIDATE_PASSWORD_PLUGIN 8 /* validate password plugin type */ #define MYSQL_GROUP_REPLICATION_PLUGIN 9 /* The Group Replication plugin */ #define MYSQL_KEYRING_PLUGIN 10 /* The Keyring plugin type */ #define MYSQL_CLONE_PLUGIN 11 /* The Clone plugin type */
例如,对于全文解析器插件,
type
值为MYSQL_FTPARSER_PLUGIN
。 info
: 指向插件的类型特定描述符的指针。此描述符的结构取决于插件的特定类型,与通用插件描述符结构不同。出于版本控制目的,每个插件类型的类型特定描述符的第一个成员应为该类型的接口版本。这使服务器能够检查每个插件的类型特定版本,无论其类型如何。在版本号之后,描述符包含任何其他所需的成员,例如回调函数和其他服务器正确调用插件所需的信息。有关编写特定类型的服务器插件的后续部分描述了其类型特定描述符的结构。-
name
: 提供插件名称的字符串。这是在mysql.plugin
表中列出的名称,您将在 SQL 语句(如INSTALL PLUGIN
和UNINSTALL PLUGIN
)中或使用--plugin-load
选项时引用插件的名称。该名称也可见于INFORMATION_SCHEMA.PLUGINS
表或SHOW PLUGINS
的输出中。插件名称不应以任何服务器选项的名称开头。如果这样做,服务器将无法初始化它。例如,服务器有一个
--socket
选项,因此您不应使用socket
、socket_plugin
等插件名称。 author
: 指示插件作者的字符串。这可以是您喜欢的任何内容。desc
: 提供插件的通用描述的字符串。这可以是您喜欢的任何内容。license
: 插件许可证类型。该值可以是PLUGIN_LICENSE_PROPRIETARY
、PLUGIN_LICENSE_GPL
或PLUGIN_LICENSE_BSD
之一。init
: 一次性初始化函数,或如果没有此类函数,则为NULL
。服务器在加载插件时执行此函数,这对于INSTALL PLUGIN
来说,或者对于列在mysql.plugin
表中的插件,是在服务器启动时发生的。该函数接受一个指向用于识别插件的内部结构的指针。它以零表示成功,以非零表示失败。deinit
: 一次性反初始化函数,或如果没有此类函数,则为NULL
。服务器在卸载插件时执行此函数,这对于UNINSTALL PLUGIN
来说,或者对于列在mysql.plugin
表中的插件,是在服务器关闭时发生的。该函数接受一个指向用于识别插件的内部结构的指针。它以零表示成功,以非零表示失败。version
: 插件版本号。安装插件后,此值可以从INFORMATION_SCHEMA.PLUGINS
表中检索。该值包含主版本号和次版本号。如果将该值写为十六进制常量,则格式为0x
,其中MMNN
MM
和NN
分别为主版本号和次版本号。例如,0x0302
表示版本 3.2。-
status_vars
: 指向与插件相关的状态变量结构的指针,或如果没有此类变量,则为NULL
。安装插件后,这些变量将显示在SHOW STATUS
语句的输出中。如果
status_vars
成员不为NULL
,则它指向一个st_mysql_show_var
结构数组,这些结构描述状态变量。请参阅 第 4.4.2.2 节“服务器插件状态和系统变量”。 -
system_vars
: 指向与插件相关的系统变量结构的指针,或如果没有此类变量,则为NULL
。这些选项和系统变量可用于帮助初始化插件内的变量。安装插件后,这些变量将显示在SHOW VARIABLES
语句的输出中。如果
system_vars
成员不为NULL
,则它指向一个st_mysql_sys_var
结构数组,这些结构描述系统变量。请参阅 第 4.4.2.2 节“服务器插件状态和系统变量”。 __reserved1
: 占位符,用于将来。它应设置为NULL
。-
flags
: 插件标志。各个位对应不同的标志。该值应设置为适用标志的 OR。这些标志可用#define PLUGIN_OPT_NO_INSTALL 1UL /* Not dynamically loadable */ #define PLUGIN_OPT_NO_UNINSTALL 2UL /* Not dynamically unloadable */ #define PLUGIN_OPT_ALLOW_EARLY 4UL /* allow --early-plugin-load */
启用时,这些标志具有以下含义
PLUGIN_OPT_NO_INSTALL
: 插件无法使用INSTALL PLUGIN
语句在运行时加载。这适用于必须在服务器启动时使用--plugin-load
、--plugin-load-add
或--early-plugin-load
选项加载的插件。PLUGIN_OPT_NO_UNINSTALL
: 插件无法使用UNINSTALL PLUGIN
语句在运行时卸载。PLUGIN_OPT_ALLOW_EARLY
: 插件可以使用--early-plugin-load
选项在服务器启动序列的早期加载。此标志对插件是否可以使用--plugin-load
或--plugin-load-add
选项在服务器启动时加载,或使用INSTALL PLUGIN
语句在运行时加载没有任何影响。
服务器仅在加载和卸载插件时调用通用插件描述符中的 init
和 deinit
函数。它们与插件的使用无关,例如当 SQL 语句导致插件被调用时。
例如,包含单个名为 simple_parser
的全文解析器插件的库的描述符信息如下所示
mysql_declare_plugin(ftexample)
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
"simple_parser", /* name */
"Oracle Corporation", /* author */
"Simple Full-Text Parser", /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
mysql_declare_plugin_end;
对于全文解析器插件,类型必须为 MYSQL_FTPARSER_PLUGIN
。这是将插件标识为在创建 FULLTEXT
索引时在 WITH PARSER
子句中合法使用。 (其他插件类型在此子句中不合法。)
plugin.h
定义了 mysql_declare_plugin()
和 mysql_declare_plugin_end
宏,如下所示
#ifndef MYSQL_DYNAMIC_PLUGIN
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int PSIZE= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin DECLS[]= {
#else
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
#endif
#define mysql_declare_plugin(NAME) \
__MYSQL_DECLARE_PLUGIN(NAME, \
builtin_ ## NAME ## _plugin_interface_version, \
builtin_ ## NAME ## _sizeof_struct_st_plugin, \
builtin_ ## NAME ## _plugin)
#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
这些声明仅在定义了 MYSQL_DYNAMIC_PLUGIN
符号时才定义 _mysql_plugin_interface_version_
符号。这意味着必须在编译命令中提供 -DMYSQL_DYNAMIC_PLUGIN
,才能将插件构建为共享库。
当宏按上述方式使用时,它们将扩展为以下代码,该代码定义了两个必需的符号(_mysql_plugin_interface_version_
和 _mysql_plugin_declarations_
)
int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION;
int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin);
struct st_mysql_plugin _mysql_plugin_declarations_[]= {
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
"simple_parser", /* name */
"Oracle Corporation", /* author */
"Simple Full-Text Parser", /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
,{0,0,0,0,0,0,0,0,0,0,0,0}}
};
前面的示例在一般描述符中声明了一个插件,但可以声明多个插件。将声明一个接一个地列在 mysql_declare_plugin()
和 mysql_declare_plugin_end
之间,并用逗号分隔。
MySQL 服务器插件必须编译为 C++ 代码。您不应使用的一种 C++ 特性是使用非常量变量初始化全局结构。结构的成员,例如 st_mysql_plugin
结构,应该只用常量变量初始化。前面显示的 simple_parser
描述符在 C++ 插件中是允许的,因为它满足该要求
mysql_declare_plugin(ftexample)
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
"simple_parser", /* name */
"Oracle Corporation", /* author */
"Simple Full-Text Parser", /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
mysql_declare_plugin_end;
以下是以另一种有效方式编写一般描述符。它使用常量变量来指示插件名称、作者和描述
const char *simple_parser_name = "simple_parser";
const char *simple_parser_author = "Oracle Corporation";
const char *simple_parser_description = "Simple Full-Text Parser";
mysql_declare_plugin(ftexample)
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
simple_parser_name, /* name */
simple_parser_author, /* author */
simple_parser_description, /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
mysql_declare_plugin_end;
但是,以下一般描述符无效。它使用结构成员来指示插件名称、作者和描述,但在 C++ 中结构不被视为常量初始化器
typedef struct
{
const char *name;
const char *author;
const char *description;
} plugin_info;
plugin_info parser_info = {
"simple_parser",
"Oracle Corporation",
"Simple Full-Text Parser"
};
mysql_declare_plugin(ftexample)
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
parser_info.name, /* name */
parser_info.author, /* author */
parser_info.description, /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
mysql_declare_plugin_end;