MySQL8 中文参考(二十一)(2)https://developer.aliyun.com/article/1566171
7.5.5 调度程序组件
注意
scheduler
组件包含在 MySQL 企业版中,这是一款商业产品。要了解更多关于商业产品的信息
截至 MySQL 8.0.34,scheduler
组件提供了mysql_scheduler
服务的实现,使应用程序、组件或插件可以每隔N秒配置、运行和取消配置任务。例如,audit_log
服务器插件在初始化时调用scheduler
组件,并配置定期刷新其内存缓存(参见启用审计日志刷新任务)。
- 目的:实现
component_scheduler.enabled
系统变量,控制调度程序是否正在执行任务。在启动时,scheduler
组件注册performance_schema.component_scheduler_tasks
表,列出当前计划任务以及关于每个任务的一些运行时数据。 - URN:
file://component_sheduler
安装说明,请参见第 7.5.1 节,“安装和卸载组件”。
scheduler
组件使用以下元素实现服务:
- 一个按照下次运行时间(升序)排序的注册的非活动计划任务的优先级队列。
- 一个注册的活动任务列表。
- 一个后台线程:
- 如果没有任务或者顶部任务需要更多时间来运行,则休眠。它会定期唤醒以检查是否到达结束时间。
- 编译需要运行的任务列表,将其从非活动队列移动到活动队列,并逐个执行每个任务。
- 执行任务列表后,将任务从活动列表中移除,添加到非活动列表,并计算它们下次需要运行的时间。
当调用者调用mysql_scheduler.create()
服务时,它会创建一个新的计划任务实例添加到队列中,这会向后台线程的信号量发送信号。将新任务的句柄返回给调用者。调用代码应保留此句柄和调度服务的引用,直到调用mysql_scheduler.destroy()
服务后。当调用者调用destroy()
并传入从create()
接收的句柄时,服务会等待任务变为非活动状态(如果正在运行),然后将其从非活动队列中移除。
组件服务调用每个应用程序提供的回调(函数指针)到同一调度线程中,依次按照每个需要运行的时间的顺序。
希望将调度队列功能整合到应用程序、组件或插件中的开发人员应查阅 MySQL 源代码分发中的 mysql_scheduler.h
文件。
7.6 MySQL 服务器插件
7.6.1 安装和卸载插件
7.6.2 获取服务器插件信息
7.6.3 MySQL 企业线程池
7.6.4 Rewriter Query Rewrite 插件
7.6.5 ddl_rewriter 插件
7.6.6 版本标记
7.6.7 Clone 插件
7.6.8 Keyring Proxy Bridge 插件
7.6.9 MySQL 插件服务
MySQL 支持一个插件 API,可以创建服务器插件。插件可以在服务器启动时加载,也可以在运行时加载和卸载而无需重新启动服务器。此接口支持的插件包括但不限于存储引擎、INFORMATION_SCHEMA
表、全文解析器插件和服务器扩展。
MySQL 发行版包括几个实现服务器扩展的插件:
- 用于验证客户端连接到 MySQL 服务器的尝试的插件。有几种认证协议的插件可用。参见第 8.2.17 节,“可插拔认证”。
- 一个连接控制插件,使管理员能够在一定数量的连续失败的客户端连接尝试之后引入逐渐增加的延迟。参见第 8.4.2 节,“连接控制插件”。
- 一个密码验证插件实现密码强度策略并评估潜在密码的强度。参见第 8.4.3 节,“密码验证组件”。
- 半同步复制插件实现了一个接口,允许源继续进行,只要至少有一个副本对每个事务做出响应。参见第 19.4.10 节,“半同步复制”。
- Group Replication 使您能够在一组 MySQL 服务器实例之间创建高可用的分布式 MySQL 服务,具有数据一致性、冲突检测和解决以及组成员服务等功能。参见第二十章,Group Replication。
- MySQL 企业版包括一个线程池插件,通过有效管理大量客户端连接的语句执行线程来增加服务器性能。参见第 7.6.3 节,“MySQL 企业线程池”。
- MySQL Enterprise Edition 包括用于监视和记录连接和查询活动的审计插件。参见第 8.4.5 节,“MySQL 企业审计”。
- MySQL Enterprise Edition 包括一个防火墙插件,实现应用级防火墙,使数据库管理员可以根据匹配接受的语句模式允许或拒绝 SQL 语句执行。参见第 8.4.7 节,“MySQL 企业防火墙”。
- 查询重写插件检查 MySQL 服务器接收到的语句,并在服务器执行之前可能对其进行重写。参见第 7.6.4 节,“重写器查询重写插件”,以及第 7.6.5 节,“ddl_rewriter 插件”。
- 版本令牌允许创建和同步服务器令牌,应用程序可以使用这些令牌来防止访问不正确或过时的数据。版本令牌基于一个实现
version_tokens
插件和一组可加载函数的插件库。参见第 7.6.6 节,“版本令牌”。 - Keyring 插件为敏感信息提供安全存储。参见第 8.4.4 节,“MySQL Keyring”。
在 MySQL 8.0.24 中,MySQL Keyring 开始从插件过渡到使用组件基础架构,通过使用名为daemon_keyring_proxy_plugin
的插件作为插件和组件服务 API 之间的桥梁来实现。参见第 7.6.8 节,“Keyring 代理桥插件”。 - X Plugin 扩展了 MySQL Server 的功能,使其能够作为文档存储库。运行 X Plugin 使 MySQL Server 能够使用 X 协议与客户端通信,该协议旨在将 MySQL 的 ACID 兼容存储能力作为文档存储库暴露出来。参见第 22.5 节,“X 插件”。
- 克隆允许从本地或远程 MySQL 服务器实例克隆
InnoDB
数据。参见第 7.6.7 节,“克隆插件”。 - 测试框架插件测试服务器服务。有关这些插件的信息,请参阅 MySQL Server Doxygen 文档中的 Plugins for Testing Plugin Services 部分,网址为
dev.mysql.com/doc/index-other.html
。
以下各节描述了如何安装和卸载插件,以及如何在运行时确定已安装的插件并获取有关它们的信息。有关编写插件的信息,请参见 MySQL 插件 API。
7.6.1 安装和卸载插件
必须在服务器中加载服务器插件才能使用它们。MySQL 支持在服务器启动和运行时加载插件。还可以在启动时控制已加载插件的激活状态,并在运行时卸载它们。
插件加载后,可以根据第 7.6.2 节“获取服务器插件信息”中的描述获取有关插件的信息。
- 安装插件
- 控制插件激活状态
- 卸载插件
- 插件和可加载函数
安装插件
在使用服务器插件之前,必须使用以下方法之一安装它。在描述中,*plugin_name
*代表插件名称,如innodb
、csv
或validate_password
。
- 内置插件
- 注册在 mysql.plugin 系统表中的插件
- 使用命令行选项命名的插件
- 使用 INSTALL PLUGIN 语句安装的插件
内置插件
服务器会自动识别内置插件。默认情况下,服务器在启动时启用插件。一些内置插件允许使用--*
plugin_name*[=*
activation_state*]
选项进行更改。
注册在 mysql.plugin 系统表中的插件
mysql.plugin
系统表用作插件的注册表(内置插件无需注册)。在正常启动序列期间,服务器会加载在表中注册的插件。默认情况下,对于从mysql.plugin
表加载的插件,服务器还会启用插件。这可以通过--*
plugin_name*[=*
activation_state*]
选项进行更改。
如果服务器使用--skip-grant-tables
选项启动,mysql.plugin
表中注册的插件将不会被加载,也将无法使用。
使用命令行选项命名的插件
位于插件库文件中的插件可以通过--plugin-load
、--plugin-load-add
或--early-plugin-load
选项在服务器启动时加载。通常,对于在启动时加载的插件,服务器还会启用该插件。这可以通过--*
plugin_name*[=*
activation_state*]
选项进行更改。
--plugin-load
和--plugin-load-add
选项在服务器启动序列期间内置插件和存储引擎初始化后加载插件。--early-plugin-load
选项用于加载必须在内置插件和存储引擎初始化之前可用的插件。
每个插件加载选项的值是一个以分号分隔的*plugin_library
和name
=
plugin_library
值的列表。每个plugin_library
是包含插件代码的库文件的名称,每个name
*是要加载的插件的名称。如果插件库的名称没有任何前置插件名称,服务器将加载库中的所有插件。有了前置插件名称,服务器将仅从库中加载指定的插件。服务器在由plugin_dir
系统变量命名的目录中查找插件库文件。
插件加载选项不会在mysql.plugin
表中注册任何插件。对于后续的重新启动,只有在再次提供--plugin-load
、--plugin-load-add
或--early-plugin-load
时,服务器才会再次加载插件。也就是说,该选项产生一次性的插件安装操作,仅持续一个服务器调用。
--plugin-load
、--plugin-load-add
和--early-plugin-load
使得即使在给定--skip-grant-tables
的情况下(导致服务器忽略mysql.plugin
表),也能加载插件。--plugin-load
、--plugin-load-add
和--early-plugin-load
还使得在启动时加载无法在运行时加载的插件成为可能。
--plugin-load-add
选项是对--plugin-load
选项的补充:
- 每个
--plugin-load
的实例都会在启动时重置要加载的插件集合,而--plugin-load-add
会向要加载的插件集合添加一个或多个插件,而不会重置当前集合。因此,如果指定了多个--plugin-load
的实例,只有最后一个会生效。对于多个--plugin-load-add
的实例,所有实例都会生效。 - 参数格式与
--plugin-load
相同,但可以使用多个--plugin-load-add
的实例来避免将大量插件作为单个长而难以控制的--plugin-load
参数进行指定。 - 可以在没有
--plugin-load
的情况下给出--plugin-load-add
,但是在--plugin-load
之前出现的任何--plugin-load-add
实例都不会生效,因为--plugin-load
会重置要加载的插件集合。
例如,这些选项:
--plugin-load=x --plugin-load-add=y
等同于这些选项:
--plugin-load-add=x --plugin-load-add=y
并且等同于这个选项:
--plugin-load="x;y"
但这些选项:
--plugin-load-add=y --plugin-load=x
等同于这个选项:
--plugin-load=x
使用 INSTALL PLUGIN 语句安装的插件
位于插件库文件中的插件可以通过INSTALL PLUGIN
语句在运行时加载。该语句还会在mysql.plugin
表中注册插件,以便导致服务器在后续重新启动时加载它。因此,INSTALL PLUGIN
需要对mysql.plugin
表的INSERT
权限。
插件库文件的基本名称取决于您的平台。Unix 和类 Unix 系统通常使用.so
作为后缀,Windows 则使用.dll
。
示例:--plugin-load-add
选项在服务器启动时安装插件。要从名为somepluglib.so
的插件库文件中安装名为myplugin
的插件,请在my.cnf
文件中使用以下行:
[mysqld] plugin-load-add=myplugin=somepluglib.so
在这种情况下,插件不会在mysql.plugin
中注册。在没有--plugin-load-add
选项的情况下重新启动服务器会导致插件在启动时不被加载。
替代地,INSTALL PLUGIN
语句会导致服务器在运行时从库文件加载插件代码:
INSTALL PLUGIN myplugin SONAME 'somepluglib.so';
INSTALL PLUGIN
还会导致“永久”插件注册:插件将列在mysql.plugin
表中,以确保服务器在后续重新启动时加载它。
许多插件可以在服务器启动时或运行时加载。但是,如果插件设计为必须在服务器启动期间加载和初始化,则尝试使用INSTALL PLUGIN
在运行时加载插件会产生错误:
mysql> INSTALL PLUGIN myplugin SONAME 'somepluglib.so'; ERROR 1721 (HY000): Plugin 'myplugin' is marked as not dynamically installable. You have to stop the server to install it.
在这种情况下,必须使用--plugin-load
、--plugin-load-add
或--early-plugin-load
。
如果插件既使用--plugin-load
、--plugin-load-add
或--early-plugin-load
选项命名,又(由于先前的INSTALL PLUGIN
语句的结果)在mysql.plugin
表中,服务器会启动,但会将这些消息写入错误日志:
[ERROR] Function '*plugin_name*' already exists [Warning] Couldn't load plugin named '*plugin_name*' with soname '*plugin_object_file*'.
控制插件激活状态
如果服务器在启动时知道插件(例如,因为插件是使用--plugin-load-add
选项命名或在mysql.plugin
表中注册的),服务器会默认加载和启用插件。可以使用--*
plugin_name*[=*
activation_state*]
启动选项来控制此类插件的激活状态,其中*plugin_name
*是要影响的插件名称,如innodb
、csv
或validate_password
。与其他选项一样,选项名称中的破折号和下划线是可以互换的。此外,激活状态值不区分大小写。例如,--my_plugin=ON
和--my-plugin=on
是等效的。
--*
plugin_name*=OFF
告诉服务器禁用插件。对于某些内置插件,如mysql_native_password
,可能无法实现。--*
plugin_name*[=ON]
告诉服务器启用插件。(不带值地指定选项为--*
plugin_name*
具有相同效果。)如果插件初始化失败,服务器将以插件禁用状态运行。--*
plugin_name*=FORCE
告诉服务器启用插件,但如果插件初始化失败,服务器将不会启动。换句话说,此选项强制服务器以插件启用或完全禁用的方式运行。--*
plugin_name*=FORCE_PLUS_PERMANENT
类似于FORCE
,但另外防止插件在运行时卸载。如果用户尝试使用UNINSTALL PLUGIN
这样做,将会出现错误。
插件激活状态可在信息模式PLUGINS
表的LOAD_OPTION
列中看到。
假设CSV
、BLACKHOLE
和ARCHIVE
是内置的可插拔存储引擎,并且您希望服务器在启动时加载它们,但要满足以下条件:如果CSV
初始化失败,服务器允许运行,必须要求BLACKHOLE
初始化成功,并且应禁用ARCHIVE
。为了实现这一点,在选项文件中使用以下行:
[mysqld] csv=ON blackhole=FORCE archive=OFF
--enable-*
plugin_name*
选项格式是--*
plugin_name*=ON
的同义词。--disable-*
plugin_name*
和--skip-*
plugin_name*
选项格式是--*
plugin_name*=OFF
的同义词。
如果插件被禁用,要么明确使用OFF
禁用,要么因为启用了ON
但初始化失败而隐式禁用,那么需要插件的服务器操作方面发生变化。例如,如果插件实现了存储引擎,那么现有的存储引擎表将变得无法访问,并且尝试为存储引擎创建新表将导致使用默认存储引擎的表,除非启用了NO_ENGINE_SUBSTITUTION
SQL 模式以导致发生错误。
禁用插件可能需要调整其他选项。例如,如果您使用--skip-innodb
启动服务器以禁用InnoDB
,则启动时可能还需要省略其他innodb_*
xxx*
选项。此外,因为InnoDB
是默认存储引擎,除非您使用--default_storage_engine
指定另一个可用的存储引擎,否则它无法启动。您还必须设置--default_tmp_storage_engine
。
卸载插件
在运行时,UNINSTALL PLUGIN
语句会禁用并卸载服务器已知的插件。该语句会卸载插件并从mysql.plugin
系统表中删除它(如果在那里注册)。因此,UNINSTALL PLUGIN
语句需要对mysql.plugin
表具有DELETE
权限。由于插件不再在表中注册,服务器在后续重新启动期间不会加载插件。
UNINSTALL PLUGIN
可以卸载插件,无论它是在运行时使用INSTALL PLUGIN
加载还是在启动时使用插件加载选项加载,但要满足以下条件:
- 无法卸载内置于服务器中的插件。这些可以通过信息模式
PLUGINS
表或SHOW PLUGINS
的输出中具有NULL
库名称的插件来识别。 - 无法卸载在服务器启动时使用
--*
plugin_name*=FORCE_PLUS_PERMANENT
启动的插件,这会阻止运行时插件的卸载。这些可以从PLUGINS
表的LOAD_OPTION
列中识别出来。
要卸载当前在服务器启动时使用插件加载选项加载的插件,请使用以下步骤。
- 从
my.cnf
文件中删除与插件相关的任何选项和系统变量。如果任何插件系统变量已经持久化到mysqld-auto.cnf
文件中,请使用RESET PERSIST *
var_name*
来逐个删除它们。 - 重新启动服务器。
- 通常情况下,插件可以通过启动时的插件加载选项或在运行时使用
INSTALL PLUGIN
来安装,但不能同时使用两者。然而,如果在某个时刻还使用了INSTALL PLUGIN
,那么仅仅从my.cnf
文件中删除插件的选项可能不足以卸载它。如果插件仍然出现在PLUGINS
或SHOW PLUGINS
的输出中,请使用UNINSTALL PLUGIN
将其从mysql.plugin
表中移除。然后再次重启服务器。
插件和可加载函数
安装插件时,可能还会自动安装相关的可加载函数。如果是这样,那么卸载插件时也会自动卸载这些函数。
7.6.2 获取服务器插件信息
有几种方法可以确定服务器中安装了哪些插件:
- 信息模式
PLUGINS
表为每个已加载的插件包含一行。任何具有PLUGIN_LIBRARY
值为NULL
的插件都是内置的,无法卸载。
mysql> SELECT * FROM INFORMATION_SCHEMA.PLUGINS\G *************************** 1\. row *************************** PLUGIN_NAME: binlog PLUGIN_VERSION: 1.0 PLUGIN_STATUS: ACTIVE PLUGIN_TYPE: STORAGE ENGINE PLUGIN_TYPE_VERSION: 50158.0 PLUGIN_LIBRARY: NULL PLUGIN_LIBRARY_VERSION: NULL PLUGIN_AUTHOR: Oracle Corporation PLUGIN_DESCRIPTION: This is a pseudo storage engine to represent the binlog in a transaction PLUGIN_LICENSE: GPL LOAD_OPTION: FORCE ... *************************** 10\. row *************************** PLUGIN_NAME: InnoDB PLUGIN_VERSION: 1.0 PLUGIN_STATUS: ACTIVE PLUGIN_TYPE: STORAGE ENGINE PLUGIN_TYPE_VERSION: 50158.0 PLUGIN_LIBRARY: ha_innodb_plugin.so PLUGIN_LIBRARY_VERSION: 1.0 PLUGIN_AUTHOR: Oracle Corporation PLUGIN_DESCRIPTION: Supports transactions, row-level locking, and foreign keys PLUGIN_LICENSE: GPL LOAD_OPTION: ON ...
SHOW PLUGINS
语句为每个已加载的插件显示一行。任何具有Library
值为NULL
的插件都是内置的,无法卸载。
mysql> SHOW PLUGINS\G *************************** 1\. row *************************** Name: binlog Status: ACTIVE Type: STORAGE ENGINE Library: NULL License: GPL ... *************************** 10\. row *************************** Name: InnoDB Status: ACTIVE Type: STORAGE ENGINE Library: ha_innodb_plugin.so License: GPL ...
mysql.plugin
表显示已经通过INSTALL PLUGIN
注册的插件。该表仅包含插件名称和库文件名称,因此提供的信息不如PLUGINS
表或SHOW PLUGINS
语句详细。
MySQL8 中文参考(二十一)(4)https://developer.aliyun.com/article/1566173