原文地址:Extending MySQL using the Component Infrastructure – part 11: performance_schema table
原文作者:LEFRED
这篇文章是关于使用组件基础架构扩展 MySQL 的系列文章中的第十一篇,上面的列表将随着新文章的发布而更新:
- 使用组件基础架构扩展 MySQL – 第 1 部分
- 使用组件基础架构扩展 MySQL - 第 2 部分:构建服务器
- 使用组件基础设施扩展 MySQL - 第 3 部分:组件服务
- 使用组件基础架构扩展 MySQL - 第 4 部分:错误日志记录
- 使用组件基础架构扩展 MySQL - 第 5 部分:权限
- 使用组件基础架构扩展 MySQL - 第 6 部分:函数
- 使用组件基础架构扩展 MySQL - 第 7 部分:给用户的消息
- 使用组件基础架构扩展 MySQL - 第 8 部分:链接第三方库
- 使用组件基础架构扩展 MySQL - 第 9 部分:添加新功能
- 使用组件基础架构扩展 MySQL - 第 10 部分:状态变量
- 使用组件基础架构扩展 MySQL - 第 11 部分:performance_schema 表
很不错,通过 MySQL 组件基础设施从而创建对 MySQL 8.0 的扩展。
本文涉及另一个重要的部分,也许是我们要实现的最复杂的部分:Performance_Schema.
这次我不会在帖子本身中包含完整的代码,只是因为代码越来越大而只包含了几个部分。GitHub 上提供了完整的源代码:https 😕/github.com/lefred/mysql-component-viruscan 。
当然,组件基础设施提供了我们创建该 pfs 表所需的服务:psf_plugin_table.
像往常一样,我们需要像这样添加包含文件和所需的服务scan.h:
#include <mysql/components/services/pfs_plugin_table_service.h>
extern REQUIRES_SERVICE_PLACEHOLDER(pfs_plugin_table);
extern REQUIRES_SERVICE_PLACEHOLDER_AS(pfs_plugin_column_integer_v1, pfs_integer);
extern REQUIRES_SERVICE_PLACEHOLDER_AS(pfs_plugin_column_string_v1, pfs_string);
extern REQUIRES_SERVICE_PLACEHOLDER_AS(pfs_plugin_column_timestamp_v2, pfs_timestamp);
您可能已经注意到,我们还必须使用 重命名服务REQUIRES_SERVICE_PLACEHOLDER_AS(),这是我为处理表中使用的数据类型的服务所做的。
我还决定将新的 Performance_Schema 表专用的大部分代码放在它自己的文件中scan_pfs.cc(在CMakeLists.txt我们已经创建的文件中:
MYSQL_ADD_COMPONENT(viruscan
scan.cc
scan_pfs.cc
MODULE_ONLY
TEST_ONLY
LINK_LIBRARIES clamav
)
在 GitHub 上查看这个要点
我们表的定义如下:
创建表`viruscan_matches`(
`LOGGED` 时间戳 NULL DEFAULT NULL,
`VIRUS` varchar(100) 默认为空,
`USER` varchar(32) 默认为 NULL,
`HOST` varchar(255) 默认为空,
`CLAMVERSION` varchar(10) 默认为空,
`SIGNATURES` int 默认 NULL
) 引擎=PERFORMANCE_SCHEMA 默认字符集=utf8mb4
整理=utf8mb4_0900_ai_ci
一旦我们创建了所有函数 (in scan_pfs.cc) 来处理表的填充、删除和解析,我们就修改了用于扫描数据的用户函数 ( viruscan_udfin scan.cc) 以检索一些安全上下文信息(用户和主机),如果发现病毒,我们在用于生成 pfs 表的数组缓冲区中添加一个条目(第282行scan.cc)。
例如,我在第69scan.h行将表的最大大小定义为 10 条记录(可能太短,我建议增加它)。
数组缓冲区用作循环缓冲区。当有新条目时,如果我们达到表中允许的最大记录数,则替换第一条记录。见第70行scan_pfs.c。
让我们看看它的样子:

现在,当我们继续扫描带有病毒的数据时,我们可以看到,当我们达到表中的最大记录数时,第一条记录被替换:

正如您在 中看到的scan_pfs.cc,当我们从表中读取列时Performance_Schema,我们需要正确处理列中存储的数据类型。并非所有 MySQL 传统数据类型都可用,我们需要使用组件服务来显示正确的值。这是我们使用短重命名服务的地方pfs_string(见第183行)。
我们的表是只读表。所以我们只需要打开/关闭表、读取记录和处理位置的函数。见第222至231行。
结论
我要再次感谢 Joro 检查并帮助我处理组件服务,还要特别感谢 Marc Alff(Mister Performance Schema)向我介绍最佳实践并清理代码。
快乐的编码,像往常一样,享受 MySQL !




