7.6.9.2 密钥环服务
MySQL Server 支持一个密钥环服务,使内部组件和插件能够安全地存储敏感信息以供以后检索。MySQL 发行版提供了一个可在两个级别访问的密钥环接口:
- 在 SQL 级别,作为一组可加载函数,每个函数映射到对服务例程的调用。
- 作为 C 语言接口,可作为服务器插件或可加载函数的插件服务调用。
本节描述如何使用密钥环服务函数在 MySQL 密钥环中存储、检索和删除密钥。有关使用函数的 SQL 接口的信息,请参阅 Section 8.4.4.15, “通用密钥环密钥管理函数”。有关一般密钥环信息,请参阅 Section 8.4.4, “MySQL 密钥环”。
密钥环服务使用启用的底层密钥环插件,如果有的话。如果没有启用密钥环插件,密钥环服务调用将失败。
密钥库中的“记录”由数据(密钥本身)和通过该标识符访问密钥的唯一标识符组成。标识符有两部分:
key_id
:密钥 ID 或名称。以mysql_
开头的key_id
值由 MySQL Server 保留。user_id
:会话有效用户 ID。如果没有用户上下文,此值可以为NULL
。该值实际上不必是“用户”;其含义取决于应用程序。
实现密钥环函数接口的函数将CURRENT_USER()
的值作为user_id
值传递给密钥环服务函数。
密钥环服务功能具有以下共同特点:
- 每个函数成功返回 0,失败返回 1。
key_id
和user_id
参数形成一个唯一组合,指示密钥环中要使用的密钥。key_type
参数提供有关密钥的附加信息,例如其加密方法或预期用途。- 密钥环服务函数将密钥 ID、用户名、类型和值视为二进制字符串,因此比较区分大小写。例如,
MyKey
和mykey
的 ID 指的是不同的密钥。
这些密钥环服务函数可用:
my_key_fetch()
从密钥环中解密并检索密钥,以及其类型。该函数为用于存储返回的密钥和密钥类型的缓冲区分配内存。当不再需要时,调用者应将内存清零或混淆,然后释放它。语法:
bool my_key_fetch(const char *key_id, const char **key_type, const char* user_id, void **key, size_t *key_len)
- 参数:
key_id
、user_id
:作为一对的以空字符结尾的字符串,形成一个唯一标识符,指示要获取哪个密钥。key_type
:缓冲区指针的地址。函数将一个指向提供有关密钥的附加信息的以空字符结尾的字符串的指针存储到其中(在添加密钥时存储)。key
:缓冲区指针的地址。函数将一个指向包含获取的密钥数据的缓冲区的指针存储到其中。key_len
:函数将*key
缓冲区的字节大小存储到一个变量的地址中。
- 返回值:
返回 0 表示成功,返回 1 表示失败。 my_key_generate()
生成给定类型和长度的新随机密钥,并将其存储在密钥环中。密钥的长度为key_len
,与从key_id
和user_id
形成的标识符相关联。类型和长度值必须与底层密钥环插件支持的值一致。请参阅第 8.4.4.13 节,“支持的密钥环密钥类型和长度”。语法:
bool my_key_generate(const char *key_id, const char *key_type, const char *user_id, size_t key_len)
- 参数:
key_id
,user_id
:作为一对形成密钥的唯一标识符的以空字符结尾的字符串。key_type
:一个以空字符结尾的字符串,提供有关密钥的附加信息。key_len
:要生成的密钥的字节大小。
- 返回值:
返回 0 表示成功,返回 1 表示失败。 my_key_remove()
从密钥环中移除一个密钥。语法:
bool my_key_remove(const char *key_id, const char* user_id)
- 参数:
key_id
,user_id
:作为一对形成要移除的密钥的唯一标识符的以空字符结尾的字符串。
- 返回值:
返回 0 表示成功,返回 1 表示失败。 my_key_store()
对密钥进行混淆并存储在密钥环中。语法:
bool my_key_store(const char *key_id, const char *key_type, const char* user_id, void *key, size_t key_len)
- 参数:
key_id
,user_id
:作为一对形成要存储的密钥的唯一标识符的以空字符结尾的字符串。key_type
:一个以空字符结尾的字符串,提供有关密钥的附加信息。key
:包含要存储的密钥数据的缓冲区。key_len
:key
缓冲区的字节大小。
- 返回值:
返回 0 表示成功,返回 1 表示失败。
7.7 MySQL 服务器可加载函数
原文:
dev.mysql.com/doc/refman/8.0/en/server-loadable-functions.html
7.7.1 安装和卸载可加载函数
7.7.2 获取有关可加载函数的信息
MySQL 支持可加载函数,即不是内置的函数,但可以在运行时(在启动期间或稍后)加载以扩展服务器功能,或卸载以移除功能。有关可加载函数的可用性描述,请参见第 14.2 节,“可加载函数参考”。可加载函数与内置(本地)函数形成对比,后者作为服务器的一部分实现并始终可用;有关表格,请参见第 14.1 节,“内置函数和运算符参考”。
注意
可加载函数以前被称为用户定义函数(UDFs)。那个术语有点不准确,因为“用户定义”也可以应用于其他类型的函数,例如存储函数(使用 SQL 编写的一种存储对象类型)和通过修改服务器源代码添加的本地函数。
MySQL 发行版包括实现这些服务器功能的可加载函数的部分或全部功能:
- 组复制使您能够在一组 MySQL 服务器实例之间创建高可用的分布式 MySQL 服务,具有数据一致性、冲突检测和解决以及内置的组成员服务。请参见第二十章,“组复制”。
- MySQL 企业版包括基于 OpenSSL 库执行加密操作的函数。请参见第 8.6 节,“MySQL 企业加密”。
- MySQL 企业版包括提供 SQL 级 API 用于掩码和去标识化操作的函数。请参见 MySQL 企业数据掩码和去标识化元素。
- MySQL 企业版包括用于监视和记录连接和查询活动的审计日志功能。请参见第 8.4.5 节,“MySQL 企业审计”,以及第 8.4.6 节,“审计消息组件”。
- MySQL 企业版包括实现应用级防火墙的防火墙功能,以使数据库管理员能够根据匹配接受语句的模式允许或拒绝 SQL 语句执行。请参见第 8.4.7 节,“MySQL 企业防火墙”。
- 查询重写器检查 MySQL Server 收到的语句,并在服务器执行之前可能对其进行重写。请参阅第 7.6.4 节,“重写器查询重写插件”
- 版本令牌使得可以创建并围绕服务器令牌进行同步,应用程序可以使用这些令牌来防止访问不正确或过时的数据。请参阅第 7.6.6 节,“版本令牌”。
- MySQL Keyring 为敏感信息提供了安全存储。请参阅第 8.4.4 节,“MySQL Keyring”。
- 锁定服务为应用程序提供了一个锁定接口。请参阅第 7.6.9.1 节,“锁定服务”。
- 函数提供了访问查询属性的接口。请参阅第 11.6 节,“查询属性”。
以下各节描述了如何安装和卸载可加载函数,以及如何在运行时确定已安装哪些可加载函数并获取有关它们的信息。
在某些情况下,可加载函数是通过安装实现该函数的组件来加载的,而不是直接加载函数。有关特定可加载函数的详细信息,请参阅包含该函数的服务器功能的安装说明。
有关编写可加载函数的信息,请参阅向 MySQL 添加函数。
7.7.1 安装和卸载可加载函数
如其名称所示,可加载函数必须在服务器中加载后才能使用。MySQL 支持在服务器启动期间自动加载函数以及随后的手动加载。
在加载可加载函数时,有关其的信息可如第 7.7.2 节“获取有关可加载函数的信息”所述获得。
- 安装可加载函数
- 卸载可加载函数
- 重新安装或升级可加载函数
安装可加载函数
要手动加载可加载函数,请使用CREATE FUNCTION
语句。例如:
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
文件基本名称取决于您的平台。Unix 和类 Unix 系统的常见后缀是.so
,Windows 的是.dll
。
CREATE FUNCTION
具有以下效果:
- 它将函数加载到服务器中,使其立即可用。
- 它在
mysql.func
系统表中注册函数,使其在服务器重新启动时保持持久性。因此,CREATE FUNCTION
需要对mysql
系统数据库的INSERT
权限。 - 它将函数添加到性能模式
user_defined_functions
表中,该表提供有关已安装可加载函数的运行时信息。参见第 7.7.2 节“获取有关可加载函数的信息”。
可加载函数的自动加载发生在正常服务器启动序列期间:
- 在
mysql.func
表中注册的函数已安装。 - 在启动时安装的组件或插件可能会自动安装相关函数。
- 自动函数安装将函数添加到性能模式
user_defined_functions
表中,该表提供有关已安装函数的运行时信息。
如果服务器使用--skip-grant-tables
选项启动,则mysql.func
表中注册的函数不会被加载,也无法使用。这不适用于组件或插件自动安装的函数。
卸载可加载函数
要删除可加载函数,请使用DROP FUNCTION
语句。例如:
DROP FUNCTION metaphon;
DROP FUNCTION
有以下影响:
- 它会卸载函数使其不可用。
- 它会从
mysql.func
系统表中删除函数。因此,DROP FUNCTION
需要对mysql
系统数据库的DELETE
权限。由于函数不再在mysql.func
表中注册,服务器在后续重新启动时不会加载该函数。 - 它会从性能模式
user_defined_functions
表中删除提供有关已安装可加载函数的运行时信息的函数。
DROP FUNCTION
不能用于删除由组件或插件自动安装而不是使用CREATE FUNCTION
安装的可加载函数。这样的函数在卸载安装它的组件或插件时也会自动删除。
重新安装或升级可加载函数
要重新安装或升级与可加载函数关联的共享库,请发出DROP FUNCTION
语句,升级共享库,然后发出CREATE FUNCTION
语句。如果先升级共享库,然后使用DROP FUNCTION
,服务器可能会意外关闭。
7.7.2 获取有关可加载函数的信息
原文:
dev.mysql.com/doc/refman/8.0/en/obtaining-loadable-function-information.html
Performance Schema user_defined_functions
表包含当前安装的可加载函数的信息:
SELECT * FROM performance_schema.user_defined_functions;
mysql.func
系统表还列出了已安装的可加载函数,但仅列出使用 CREATE FUNCTION
安装的函数。user_defined_functions
表列出了使用 CREATE FUNCTION
安装的可加载函数,以及由组件或插件自动安装的可加载函数。这种差异使得 user_defined_functions
比 mysql.func
更适合检查已安装的可加载函数。参见 Section 29.12.21.10, “用户定义函数表”。
7.8 在一台机器上运行多个 MySQL 实例
7.8.1 设置多个数据目录
7.8.2 在 Windows 上运行多个 MySQL 实例
7.8.3 在 Unix 上运行多个 MySQL 实例
7.8.4 在多服务器环境中使用客户端程序
在某些情况下,您可能希望在单台机器上运行多个 MySQL 实例。您可能希望在保持现有生产设置不受干扰的同时测试新的 MySQL 发布版。或者您可能希望为不同的用户提供对他们自己管理的不同 mysqld 服务器的访问权限。(例如,您可能是一个希望为不同客户提供独立的 MySQL 安装的互联网服务提供商。)
每个实例可以使用不同的 MySQL 服务器二进制文件,或者对多个实例使用相同的二进制文件,或者两种方法的任意组合。例如,您可以从 MySQL 5.7 运行一个服务器,从 MySQL 8.0 运行另一个服务器,以查看不同版本如何处理给定的工作负载。或者您可以运行当前生产版本的多个实例,每个实例管理不同的数据库集。
无论您是否使用不同的服务器二进制文件,您运行的每个实例都必须配置具有几个操作参数的唯一值。这消除了实例之间冲突的可能性。参数可以在命令行上设置,选项文件中设置,或通过设置环境变量设置。请参见 Section 6.2.2, “指定程序选项”。要查看给定实例使用的值,请连接到该实例并执行 SHOW VARIABLES
语句。
MySQL 实例管理的主要资源是数据目录。每个实例应该使用不同的数据目录,其位置使用 --datadir=*
dir_name*
选项指定。有关配置每个实例使用自己的数据目录的方法,以及未能这样做的危险的警告,请参见 Section 7.8.1, “设置多个数据目录”。
除了使用不同的数据目录外,几个其他选项必须为每个服务器实例具有不同的值:
--port=*
port_num*
--port
控制 TCP/IP 连接的端口号。或者,如果主机有多个网络地址,您可以设置bind_address
系统变量,使每个服务器监听不同的地址。--socket={*
file_name*|*
pipe_name*}
--socket
控制 Unix 上的 Unix 套接字文件路径或 Windows 上的命名管道名称。在 Windows 上,仅需要为允许命名管道连接的服务器指定不同的管道名称。--shared-memory-base-name=*
name*
此选项仅在 Windows 上使用。它指定 Windows 服务器用于允许客户端使用共享内存连接的共享内存名称。仅需要为允许共享内存连接的服务器指定不同的共享内存名称。--pid-file=*
file_name*
此选项指示服务器写入其进程 ID 的文件的路径名。
如果您使用以下日志文件选项,则它们的值必须对每个服务器不同:
--general_log_file=*
file_name*
--log-bin[=*
file_name*]
--slow_query_log_file=*
file_name*
--log-error[=*
file_name*]
有关日志文件选项的进一步讨论,请参见 第 7.4 节,“MySQL 服务器日志”。
为了获得更好的性能,您可以为每个服务器单独指定以下选项,以在几个物理磁盘之间分散负载:
--tmpdir=*
dir_name*
拥有不同的临时目录还可以更容易地确定哪个 MySQL 服务器创建了任何给定的临时文件。
如果您在不同位置安装了多个 MySQL 实例,可以使用 --basedir=*dir_name*
选项为每个安装指定基目录。这会导致每个实例自动使用不同的数据目录、日志文件和 PID 文件,因为这些参数的默认值都是相对于基目录的。在这种情况下,您需要指定的其他选项只有 --socket
和 --port
选项。假设您使用 tar
文件二进制发行版安装了不同版本的 MySQL。这些安装在不同的位置,因此您可以在相应的基目录下使用命令 bin/mysqld_safe 启动每个安装的服务器。mysqld_safe 确定要传递给 mysqld 的正确 --basedir
选项,您只需指定给 mysqld_safe 的 --socket
和 --port
选项。
如下节所讨论的,可以通过指定适当的命令选项或设置环境变量来启动额外的服务器。但是,如果您需要更长期地运行多个服务器,最方便的方法是使用选项文件为每个服务器指定那些必须对其唯一的选项值。--defaults-file
选项对此很有用。
7.8.1 设置多个数据目录
原文:
dev.mysql.com/doc/refman/8.0/en/multiple-data-directories.html
机器上的每个 MySQL 实例应该有自己的数据目录。位置是使用--datadir=*
dir_name*
选项指定的。
有不同的方法来为新实例设置数据目录:
- 创建一个新的数据目录。
- 复制现有数据目录。
以下讨论提供了有关每种方法的更多详细信息。
警告
通常,您不应该有两个更新同一数据库中数据的服务器。如果您的操作系统不支持无故障系统锁定,这可能会导致令人不快的惊喜。如果(尽管有此警告)您运行使用相同数据目录的多个服务器,并且它们启用了日志记录,则必须使用适当的选项来指定每个服务器唯一的日志文件名。否则,服务器会尝试记录到相同的文件。
即使遵守了前面的预防措施,这种设置仅适用于MyISAM
和MERGE
表,而不适用于任何其他存储引擎。此外,在 NFS 环境中,始终不要在多个服务器之间共享数据目录。允许多个 MySQL 服务器通过 NFS 访问共享数据目录是非常糟糕的想法。主要问题是 NFS 是速度瓶颈。它不适用于这种用途。NFS 的另一个风险是你必须想出一种方法来确保两个或更多服务器不会相互干扰。通常,NFS 文件锁定由lockd
守护程序处理,但目前没有平台可以在任何情况下 100%可靠地执行锁定。
创建一个新的数据目录
使用此方法,数据目录的状态与您首次安装 MySQL 时相同,并且具有默认的 MySQL 帐户集和没有用户数据。
在 Unix 上,初始化数据目录。参见第 2.9 节,“安装后设置和测试”。
在 Windows 上,数据目录包含在 MySQL 发行版中:
- Windows 的 MySQL Zip 存档发行版包含一个未修改的数据目录。您可以将这样的发行版解压缩到临时位置,然后将
data
目录复制到您设置新实例的位置。 - Windows MSI 软件包安装程序创建并设置安装的服务器使用的数据目录,但还创建一个干净的“模板”数据目录,名称为
data
,位于安装目录下。使用 MSI 软件包执行安装后,可以复制模板数据目录以设置其他 MySQL 实例。
复制现有数据目录。
使用此方法,数据目录中存在的任何 MySQL 帐户或用户数据都将转移到新的数据目录。
- 停止使用数据目录的现有 MySQL 实例。这必须是一个干净的关闭,以便实例将任何未决更改刷新到磁盘。
- 将数据目录复制到新数据目录应该所在的位置。
- 复制现有实例使用的
my.cnf
或my.ini
选项文件。这将作为新实例的基础。 - 修改新的选项文件,使得任何指向原数据目录的路径都指向新数据目录。同时,修改任何其他必须在每个实例中唯一的选项,比如 TCP/IP 端口号和日志文件。有关必须在每个实例中唯一的参数列表,请参见第 7.8 节,“在一台机器上运行多个 MySQL 实例”。
- 启动新实例,并告诉它使用新的选项文件。
7.8.2 在 Windows 上运行多个 MySQL 实例
原文:
dev.mysql.com/doc/refman/8.0/en/multiple-windows-servers.html
7.8.2.1 在 Windows 命令行上启动多个 MySQL 实例
7.8.2.2 启动多个 MySQL 实例作为 Windows 服务
您可以通过从命令行手动启动每个具有适当操作参数的服务器,或者通过将多个服务器安装为 Windows 服务并以此方式运行它们,在 Windows 上运行多个服务器。有关从命令行或作为服务运行 MySQL 的一般说明,请参见第 2.3 节,“在 Microsoft Windows 上安装 MySQL”。以下各节描述了如何为每个服务器启动具有不同值的那些必须对每个服务器唯一的选项,例如数据目录。这些选项在第 7.8 节,“在一台机器上运行多个 MySQL 实例”中列出。
原文:
dev.mysql.com/doc/refman/8.0/en/multiple-windows-command-line-servers.html
7.8.2.1 在 Windows 命令行上启动多个 MySQL 实例
从命令行手动启动单个 MySQL 服务器的过程在 Section 2.3.4.6, “Starting MySQL from the Windows Command Line”中有描述。要以这种方式启动多个服务器,可以在命令行或选项文件中指定适当的选项。将选项放在选项文件中更方便,但必须确保每个服务器都有自己的选项集。为此,请为每个服务器创建一个选项文件,并在运行时使用--defaults-file
选项告诉服务器文件名。
假设您想要在端口 3307 上运行一个mysqld实例,数据目录为C:\mydata1
,另一个实例在端口 3308 上,数据目录为C:\mydata2
。使用以下步骤:
- 确保每个数据目录都存在,包括包含授权表的
mysql
数据库的副本。 - 创建两个选项文件。例如,创建一个名为
C:\my-opts1.cnf
的文件,内容如下:
[mysqld] datadir = C:/mydata1 port = 3307
- 创建第二个名为
C:\my-opts2.cnf
的文件,内容如下:
[mysqld] datadir = C:/mydata2 port = 3308
- 使用
--defaults-file
选项启动每个服务器时都使用自己的选项文件:
C:\> C:\mysql\bin\mysqld --defaults-file=C:\my-opts1.cnf C:\> C:\mysql\bin\mysqld --defaults-file=C:\my-opts2.cnf
- 每个服务器都在前台运行(直到服务器稍后退出时不会出现新提示),因此您需要在单独的控制台窗口中发出这两个命令。
要关闭服务器,请使用适当的端口号连接到每个服务器:
C:\> C:\mysql\bin\mysqladmin --port=3307 --host=127.0.0.1 --user=root --password shutdown C:\> C:\mysql\bin\mysqladmin --port=3308 --host=127.0.0.1 --user=root --password shutdown
如上所述配置的服务器允许客户端通过 TCP/IP 连接。如果您的 Windows 版本支持命名管道,并且您还希望允许命名管道连接,请指定启用命名管道的选项并指定其名称。支持命名管道连接的每个服务器必须使用唯一的管道名称。例如,C:\my-opts1.cnf
文件可能如下所示:
[mysqld] datadir = C:/mydata1 port = 3307 enable-named-pipe socket = mypipe1
类似地修改C:\my-opts2.cnf
以供第二个服务器使用。然后按照先前描述的方式启动服务器。
对于希望允许共享内存连接的服务器,也适用类似的过程。通过启动具有启用shared_memory
系统变量的服务器,并通过设置shared_memory_base_name
系统变量来为每个服务器指定唯一的共享内存名称,启用此类连接。
原文:
dev.mysql.com/doc/refman/8.0/en/multiple-windows-services.html
7.8.2.2 启动多个 MySQL 实例作为 Windows 服务
在 Windows 上,MySQL 服务器可以作为 Windows 服务运行。有关安装、控制和删除单个 MySQL 服务的过程,请参阅 Section 2.3.4.8, “Starting MySQL as a Windows Service”。
要设置多个 MySQL 服务,您必须确保每个实例除了其他必须针对每个实例唯一的参数外,还使用不同的服务名称。
对于以下说明,假设您想从分别安装在C:\mysql-5.7.9
和C:\mysql-8.0.36
的两个不同版本的 MySQL 运行mysqld服务器。(如果您正在运行 5.7.9 作为生产服务器,但也想使用 8.0.36 进行测试,可能会出现这种情况。)
要将 MySQL 安装为 Windows 服务,请使用--install
或--install-manual
选项。有关这些选项的信息,请参阅 Section 2.3.4.8, “Starting MySQL as a Windows Service”。
根据前面的信息,您有几种设置多个服务的方法。以下说明描述了一些示例。在尝试任何方法之前,请关闭并删除任何现有的 MySQL 服务。
- 方法 1: 在一个标准选项文件中为所有服务指定选项。为此,为每个服务器使用不同的服务名称。假设您想要使用服务名称
mysqld1
运行 5.7.9 mysqld,并使用服务名称mysqld2
运行 8.0.36 mysqld。在这种情况下,您可以为 5.7.9 使用[mysqld1]
组,为 8.0.36 使用[mysqld2]
组。例如,您可以像这样设置C:\my.cnf
:
# options for mysqld1 service [mysqld1] basedir = C:/mysql-5.7.9 port = 3307 enable-named-pipe socket = mypipe1 # options for mysqld2 service [mysqld2] basedir = C:/mysql-8.0.36 port = 3308 enable-named-pipe socket = mypipe2
- 安装服务如下,使用完整的服务器路径名确保 Windows 为每个服务注册正确的可执行程序:
C:\> C:\mysql-5.7.9\bin\mysqld --install mysqld1 C:\> C:\mysql-8.0.36\bin\mysqld --install mysqld2
- 要启动服务,请使用服务管理器,或使用适当的服务名称使用NET START或SC START:
C:\> SC START mysqld1 C:\> SC START mysqld2
- 要停止服务,请使用服务管理器,或使用适当的服务名称使用NET STOP或SC STOP:
C:\> SC STOP mysqld1 C:\> SC STOP mysqld2
- 方法 2: 在单独的文件中为每个服务器指定选项,并在安装服务时使用
--defaults-file
告诉每个服务器要使用哪个文件。在这种情况下,每个文件应该使用[mysqld]
组列出选项。
使用这种方法,要为 5.7.9 mysqld指定选项,请创建一个看起来像这样的文件C:\my-opts1.cnf
:
[mysqld] basedir = C:/mysql-5.7.9 port = 3307 enable-named-pipe socket = mypipe1
- 对于 8.0.36 版本的mysqld,创建一个名为
C:\my-opts2.cnf
的文件,内容如下:
[mysqld] basedir = C:/mysql-8.0.36 port = 3308 enable-named-pipe socket = mypipe2
- 安装服务的步骤如下(每个命令单独一行输入):
C:\> C:\mysql-5.7.9\bin\mysqld --install mysqld1 --defaults-file=C:\my-opts1.cnf C:\> C:\mysql-8.0.36\bin\mysqld --install mysqld2 --defaults-file=C:\my-opts2.cnf
- 当将 MySQL 服务器安装为服务并使用
--defaults-file
选项时,服务名称必须在选项之前。
安装服务后,启动和停止服务的方法与前面的示例相同。
要删除多个服务,请对每个服务使用SC DELETE mysqld_service_name
。或者,对每个服务使用mysqld --remove,在--remove
选项后指定服务名称。如果服务名称是默认值(MySQL
),在使用mysqld --remove时可以省略它。
MySQL8 中文参考(二十三)(2)https://developer.aliyun.com/article/1566146