每个包含服务器插件的插件库必须包含一个库描述符,该描述符包含文件中每个服务器插件的通用插件描述符。本节讨论如何为服务器插件编写库和通用描述符。
标准库描述符必须定义两个符号:
_mysql_plugin_interface_version_
指定通用插件框架的版本号。这是由MYSQL_PLUGIN_INTERFACE_VERSION
中定义的plugin.h
文件。_mysql_plugin_declarations_
定义插件声明数组,以所有成员都设置为0的声明结束。类的一个实例st_mysql_plugin
结构(也定义在plugin.h
).库中的每个服务器插件都必须有一个这样的插件。
如果服务器在一个库中没有找到这两个符号,它就不接受它为合法的插件库,并拒绝它并报错。这就防止了将库用于插件目的,除非它是专门作为插件库构建的。
定义两个必需符号的传统方法是使用mysql_declare_plugin ()
而且mysql_declare_plugin_end
宏的plugin.h
文件:
mysql_declare_plugin (的名字)...一个或多个服务器插件描述符在这里…mysql_declare_plugin_end;
每个服务器插件必须有一个通用描述符,为服务器插件API提供信息。通用描述符对所有插件类型具有相同的结构。的st_mysql_plugin
结构plugin.h
File定义了这个描述符:
Struct st_mysql_plugin {int类型;/*插件类型(MYSQL_XXX_PLUGIN值)*/ void *info;/*指向特定类型的插件描述符的指针/*插件名*/ const char *作者;/*插件作者(for I_S.PLUGINS) */ const char *descr;/*通用描述文本(用于I_S.PLUGINS) */ int许可证;/*插件许可证(PLUGIN_LICENSE_XXX) */ int (*init)(void *);/*加载插件时调用的函数*/ int (*deinit)(void *);/*卸载插件时调用的函数*/ unsigned int版本;/*插件版本(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 *
成员应该指定为以空结束的字符串。
类型
:插件类型。的插件类型值之一plugin.h
:/ *允许类型的插件* / # define MYSQL_UDF_PLUGIN 0 / *用户定义函数* / # define MYSQL_STORAGE_ENGINE_PLUGIN 1 / *存储引擎* / # define MYSQL_FTPARSER_PLUGIN 2 / *全文解析器插件* / 3 # define MYSQL_DAEMON_PLUGIN / *守护进程/原始插件类型* / # define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 / * I_S插件类型* / # define MYSQL_AUDIT_PLUGIN 5 / *审计插件类型* / # define MYSQL_REPLICATION_PLUGIN 6 / *复制插件类型* / #定义MYSQL_AUTHENTICATION_PLUGIN 7 /*认证插件类型*/…
例如,对于全文解析器插件,可以使用
类型
值是MYSQL_FTPARSER_PLUGIN
.信息
:指向插件的特定类型描述符的指针。与一般的插件描述符结构不同,这个描述符的结构取决于插件的特定类型。出于版本控制的目的,每个插件类型的类型特定描述符的第一个成员应该是该类型的接口版本。这使服务器能够检查每个插件的特定类型版本,无论其类型是什么。在版本号之后,描述符包括任何其他需要的成员,比如回调函数和服务器正确调用插件所需的其他信息。后面关于编写特定类型的服务器插件的部分将描述它们特定于类型的描述符的结构。的名字
:给出插件名称的字符串。这个名字会被列在mysql.plugin
表,通过它可以在SQL语句中引用插件,例如安装插件
而且卸载插件
,或与——plugin-load
选择。名称也可以在INFORMATION_SCHEMA。插件
表或的输出显示插件
.插件名称不应该以任何服务器选项的名称开头。如果是,服务器将无法初始化它。例如,服务器有一个
——套接字
选项,所以你不应该使用插件名,例如套接字
,socket_plugin
等等。作者
:命名插件作者的字符串。这可以是任何你喜欢的。desc
:提供插件的一般描述的字符串。这可以是任何你喜欢的。许可证
:插件的license类型。取值为之一PLUGIN_LICENSE_PROPRIETARY
,PLUGIN_LICENSE_GPL
,或PLUGIN_LICENSE_BSD
.初始化
:一次初始化函数,或零
如果没有这样的函数。服务器在加载插件时执行此函数安装插件
中列出的插件mysql.plugin
表,在服务器启动时。该函数接受一个参数,该参数指向用于标识插件的内部结构。它返回0表示成功,返回非0表示失败。deinit
:一次反初始化函数,或零
如果没有这样的函数。服务器在卸载插件时执行此函数卸载插件
中列出的插件mysql.plugin
表,在服务器关闭时。函数有一个参数,指向用于标识插件的内部结构。它返回0表示成功,返回非0表示失败。版本
:插件版本号。插件安装后,可以从INFORMATION_SCHEMA。插件
表格包括主号和副号。如果将值写成十六进制常量,则格式为0 x
,在那里MMNN
毫米
而且神经网络
分别是主号和副号。例如,0 x0302
代表了3.2版本。status_vars
:指向与插件相关的状态变量结构的指针零
如果没有这样的变量。插件安装后,这些变量将显示在显示状态
声明。的
status_vars
成员,如果不是零
的数组st_mysql_show_var
描述状态变量的结构。看到第4.4.2.2节“服务器插件状态和系统变量”.system_vars
:指向与插件相关的系统变量结构的指针零
如果没有这样的变量。这些选项和系统变量可以用来帮助初始化插件中的变量。插件安装后,这些变量将显示在显示变量
声明。的
system_vars
成员,如果不是零
的数组st_mysql_sys_var
描述系统变量的结构。看到第4.4.2.2节“服务器插件状态和系统变量”.__reserved1
:未来的占位符。应该设置为零
.旗帜
:插件的旗帜。每个位对应不同的标志。该值应该设置为适用标志的OR。以下是可用的标志:#define PLUGIN_OPT_NO_INSTALL 1UL /*不可动态加载*/ #define PLUGIN_OPT_NO_UNINSTALL 2UL /*不可动态加载*/
这些标志在启用时具有以下含义:
PLUGIN_OPT_NO_INSTALL
:插件无法在运行时加载安装插件
声明。这适用于必须在服务器启动时用——plugin-load
或——plugin-load-add
选择。PLUGIN_OPT_NO_UNINSTALL
:该插件无法在运行时卸载卸载插件
声明。
服务器调用初始化
而且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函数(加载时)*/ simple_parser_plugin_deinit,/* deinit函数(卸载时)*/ 0x0001, /* version */ simple_status, /*状态变量*/ simple_system_variables,/*系统变量*/ NULL, 0} mysql_declare_plugin_end;
对于全文解析器插件,类型必须为MYSQL_FTPARSER_PLUGIN
.该值标识插件是否合法,可以在与解析器
子句时创建全文
索引。(对于这个子句,没有其他插件类型是合法的。)
plugin.h
定义了mysql_declare_plugin ()
而且mysql_declare_plugin_end
宏是这样的:
# 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}}
这些声明定义了_mysql_plugin_interface_version_
符号仅当MYSQL_DYNAMIC_PLUGIN
符号定义。这意味着-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_[] ={{/ *类型* / &simple_parser_descriptor MYSQL_FTPARSER_PLUGIN, / *描述符* / " simple_parser " / *姓名* /“甲骨文公司”,作者/ * * /”简单全文解析器“,/ * * / PLUGIN_LICENSE_GPL描述,/ *插件许可证* / simple_parser_plugin_init, / * init函数(加载)* / simple_parser_plugin_deinit, / * deinit函数(卸载)* / 0 x0001, / * * / simple_status版本,/ * * / simple_system_variables状态变量,/ *系统变量* /空,0},{0,0,0,0,0,0,0,0,0,0,0,0}}};
上面的例子在通用描述符中声明了一个插件,但是也可以声明多个插件。依次列出之间的声明mysql_declare_plugin ()
而且mysql_declare_plugin_end
,以逗号分隔。
MySQL服务器插件可以用C或c++(或其他可以使用C调用约定的语言)编写。如果你编写一个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函数(加载时)*/ simple_parser_plugin_deinit,/* deinit函数(卸载时)*/ 0x0001, /* version */ simple_status, /*状态变量*/ simple_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 = "简单全文解析器";mysql_declare_plugin (ftexample){/ *类型* / &simple_parser_descriptor MYSQL_FTPARSER_PLUGIN, / *描述符* / simple_parser_name, / *姓名* / simple_parser_author, / * * / simple_parser_description作者/ * * / PLUGIN_LICENSE_GPL描述,/ *插件许可证* / simple_parser_plugin_init, / * init函数(加载)* / simple_parser_plugin_deinit, / * deinit函数(卸载)* / 0 x0001, / * * / simple_status版本,/ * * / simple_system_variables状态变量,/*系统变量*/ NULL, 0} mysql_declare_plugin_end;
但是,下面的通用描述符无效。它使用结构成员来指示插件名称、作者和描述,但在c++中,结构不被认为是常量初始化式:
Typedef结构{const char *name;const char *作者;const char *描述;} 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.name。作者,/* 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;