扩展 MySQL 5.7  /  第 5 章 MySQL 插件服务

第 5 章 MySQL 插件服务

MySQL 服务器插件可以访问服务器插件服务”。插件服务接口公开了插件可以调用的服务器功能。它补充了插件 API 并具有以下特征:

  • 服务使插件能够使用普通函数调用访问服务器内部的代码。服务也可用于可加载函数。

  • 服务是可移植的,可以在多个平台上工作。

  • 该接口包括一个版本控制机制,以便可以在加载时根据插件版本检查服务器支持的服务版本。版本控制防止服务器提供的服务版本与插件预期或要求的服务版本之间的不兼容。

  • 有关用于测试插件服务的插件的信息,请参阅 MySQL Server Doxygen 文档的用于测试插件服务的插件部分,该文档位于 https://mysql.net.cn/doc/index-other.html

插件服务接口与插件 API 的不同之处如下:

  • 插件 API 使插件能够被服务器使用。调用主动权在于服务器调用插件。这使插件能够扩展服务器功能或注册以接收有关服务器处理的通知。

  • 插件服务接口使插件能够调用服务器内部的代码。调用主动权在于插件调用服务功能。这使得已经在服务器中实现的功能可以被许多插件使用;他们不需要自己单独实施。

要确定存在哪些服务以及它们提供哪些功能,请查看include/mysqlMySQL 源代码分发目录。相关文件是:

  • plugin.hincludes services.h,这是包含所有可用的服务特定头文件的 伞状头文件。

  • 特定于服务的标头具有 . service_xxx.h

每个特定于服务的标头都应包含注释,为给定服务提供完整的使用文档,包括可用的服务功能、它们的调用顺序和返回值。

对于希望修改服务器以添加新服务的开发人员,请参阅 MySQL 内部结构:插件的 MySQL 服务

可用的服务包括:

  • locking_service:实现锁的服务,具有三个属性:锁命名空间、锁名称和锁模式。此锁定接口可在两个级别访问:1) 在 SQL 级别,作为一组可加载函数,每个函数都映射到对服务例程的调用;2) 作为 C 语言接口,可作为服务器插件或可加载函数的插件服务调用。有关详细信息,请参阅 锁定服务

  • my_plugin_log_service:一种使插件能够报告错误并指定错误消息的服务。服务器将消息写入其错误日志。

  • my_snprintf:一种字符串格式化服务,可跨平台生成一致的结果。

  • my_thd_scheduler:插件选择线程调度程序的服务。

  • mysql_keyring:密钥环存储服务,可在两个级别访问:1)在 SQL 级别,作为一组可加载函数,每个函数映射到对服务例程的调用;2) 作为 C 语言接口,可作为服务器插件或可加载函数的插件服务调用。有关详细信息,请参阅密钥环服务

  • mysql_password_policy:用于密码验证和强度检查的服务。

  • mysql_string:字符串操作服务。

  • security_context:一种使插件能够检查或操作线程安全上下文的服务。此服务提供 setter 和 getter 例程来访问服务器Security_context 类的属性,其中包括操作系统用户和主机、经过身份验证的用户和主机以及客户端 IP 地址等属性。

  • thd_alloc: 内存分配服务。

  • thd_wait:插件报告何时休眠或停止的服务。

本节的其余部分描述了插件如何使用作为服务提供的服务器功能。另请参阅使用该 服务的守护进程”示例插件的源代码。my_snprintf在 MySQL 源代码分发中,该插件位于 plugin/daemon_example目录中。

要在插件中使用一个或多个服务,插件源文件必须包含plugin.h头文件以访问与服务相关的信息:

#include <mysql/plugin.h>

这并不代表任何额外的设置成本。无论如何,插件必须包含该文件,因为它包含每个插件都需要的定义和结构。

要访问服务,插件会像调用任何其他函数一样调用服务函数。例如,要将字符串格式化为打印缓冲区,调用my_snprintf()同名服务提供的函数:

char buffer[BUFFER_SIZE];

my_snprintf(buffer, sizeof(buffer), format_string, argument_to_format, ...);

要报告服务器将写入错误日志的错误,首先选择一个错误级别。 mysql/service_my_plugin_log.h定义这些级别:

enum plugin_log_level
{
  MY_ERROR_LEVEL,
  MY_WARNING_LEVEL,
  MY_INFORMATION_LEVEL
};

然后调用my_plugin_log_message()

int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
                          const char *format, ...);

例如:

my_plugin_log_message(plugin_ptr, MY_ERROR_LEVEL, "Cannot initialize plugin");

插件的 某些服务可能 插件提供,因此只有在加载提供服务的插件时才可用。任何使用此类服务​​的 MySQL 组件都应检查该服务是否可用。

当你构建你的插件时, -lmysqlservices在链接时使用标志来链接libmysqlservices库。例如,对于 CMake,将其放在顶级 CMakeLists.txt文件中:

FIND_LIBRARY(MYSQLSERVICES_LIB mysqlservices
 PATHS "${MYSQL_SRCDIR}/libservices" NO_DEFAULT_PATH)

将其放入CMakeLists.txt包含插件源的目录中的文件中:

# the plugin needs the mysql services library for error logging
TARGET_LINK_LIBRARIES (your_plugin_library_name ${MYSQLSERVICES_LIB})