暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

一个简单的MySQL插件来检索系统指标

原创 小小亮 2020-07-10
768

你是否曾经想扩展MySQL并添加一些您认为缺少的功能? 使用MySQL插件,您可以完全做到这一点。有件事令我困扰,无法轻松地从MySQL内部检索系统指标。无论我是通过远程连接进行连接,还是希望为监视添加功能而不需要与服务器建立另一个接口,我都希望在不离开MySQL接口的情况下检索系统指标。

image.png

因此,我为此进行了概念验证。我的目标是获取诸如RAM(总,已使用,可用),系统负载,CPU利用率,包含datadir的文件系统的磁盘利用率等指标。我的目标是在MySQL中尽可能有效地做到这一点。为此,我选择在尽可能少的代码行中使用标准C库,而不必抓取系统文件或运行命令来获取数据。按需提取数据,以免增加系统负载。

以下是我创建的用于获取一些系统指标的基本插件的示例

对于此插件,我选择通过INFORMATION_SCHEMA.OS_METRICS访问数据。这在以下插件中定义:

static struct st_mysql_information_schema simple_table_info = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
 
static ST_FIELD_INFO simple_table_fields[]=
{
{"NAME", 15, MYSQL_TYPE_STRING, 0, 0, 0, 0},
{"VALUE", 6, MYSQL_TYPE_FLOAT, 0, MY_I_S_UNSIGNED, 0, 0},
{"COMMENT", 50, MYSQL_TYPE_STRING, 0, 0, 0, 0},
{0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0}
};
 
static int simple_fill_table(THD *thd, TABLE_LIST *tables, Item *cond)
{
struct sysinfo info;
TABLE *table= tables->table;

这将虚拟表的结构定义为具有三列:NAME,VALUE和COMMENT。NAME的字符串长度最多为15个字符,其后是VALUE的浮点数,而字符串则是COMMENT,长度最多为50个字符。

通过在C语言中调用sysinfo()函数,我可以提取各种指标。这些指标以结构形式返回。然后可以使用以下命令将它们传递到OS_METRICS“表”中:

这将虚拟表的结构定义为具有三列:NAME,VALUE和COMMENT。NAME的字符串长度最多为15个字符,其后是VALUE的浮点数,而字符串则是COMMENT,长度最多为50个字符。

通过在C语言中调用sysinfo()函数,我可以提取各种指标。这些指标以结构形式返回。然后可以使用以下命令将它们传递到OS_METRICS“表”中:

在上述情况下,我从sysinfo结构中引用了元素“ totalram”,并将其存储在表中。您可以看到表的每一列都有一行,并且值被逐一存储。

这是插件的最基本形式,该插件仅提取RAM信息并使之在INFORMATION_SCHEMA.OS_METRICS中可用:

#include <sql_class.h>
#include <table.h>
#include <stdlib.h>
#include <ctype.h>
#include <mysql_version.h>
#include <mysql/plugin.h>
#include <my_global.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/sysinfo.h>

static struct st_mysql_information_schema simple_table_info = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };

static ST_FIELD_INFO simple_table_fields[]=
{
{"NAME", 15, MYSQL_TYPE_STRING, 0, 0, 0, 0},
{"VALUE", 6, MYSQL_TYPE_FLOAT, 0, MY_I_S_UNSIGNED, 0, 0},
{"COMMENT", 50, MYSQL_TYPE_STRING, 0, 0, 0, 0},
{0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0}
};

static int simple_fill_table(THD *thd, TABLE_LIST *tables, Item *cond)
{
struct sysinfo info;
TABLE *table= tables->table;

sysinfo(&info);

// Total usable main memory size
table->field[0]->store("TOTAL_RAM", 9, system_charset_info);
table->field[1]->store(info.totalram * info.mem_unit);
table->field[2]->store("Total usable main memory size", 29, system_charset_info);
if (schema_table_store_record(thd, table)) return 1;

// Available memory size
table->field[0]->store("FREE_RAM", 8, system_charset_info);
table->field[1]->store(info.freeram * info.mem_unit);
table->field[2]->store("Available memory size", 21, system_charset_info);
if (schema_table_store_record(thd, table)) return 1;

// Used memory size
table->field[0]->store("USED_RAM", 8, system_charset_info);
table->field[1]->store((info.totalram - info.freeram) * info.mem_unit);
table->field[2]->store("Used memory size", 16, system_charset_info);
if (schema_table_store_record(thd, table)) return 1;

// Available memory (percentage)
table->field[0]->store("FREE_RAM_PCT", 12, system_charset_info);
table->field[1]->store((float) info.freeram / info.totalram * 100 * info.mem_unit);
table->field[2]->store("Available memory as a percentage", 32, system_charset_info);
if (schema_table_store_record(thd, table)) return 1;

// Used memory (percentage)
table->field[0]->store("USED_RAM_PCT", 12, system_charset_info);
table->field[1]->store((float) (info.totalram - info.freeram) / info.totalram * 100 * info.mem_unit);
table->field[2]->store("Free memory as a percentage", 27, system_charset_info);
if (schema_table_store_record(thd, table)) return 1;

// Amount of shared memory
table->field[0]->store("SHARED_RAM", 10, system_charset_info);
table->field[1]->store(info.sharedram * info.mem_unit);
table->field[2]->store("Amount of shared memory", 23, system_charset_info);
if (schema_table_store_record(thd, table)) return 1;

// Memory used by buffers
table->field[0]->store("BUFFER_RAM", 10, system_charset_info);
table->field[1]->store(info.bufferram * info.mem_unit);
table->field[2]->store("Memory used by buffers", 22, system_charset_info);
if (schema_table_store_record(thd, table)) return 1;

return 0;
}

static int simple_table_init(void *ptr)
{
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE*)ptr;
schema_table->fields_info= simple_table_fields;
schema_table->fill_table= simple_fill_table;
return 0;
}

mysql_declare_plugin(os_metrics)
{
MYSQL_INFORMATION_SCHEMA_PLUGIN,
&simple_table_info, /* type-specific descriptor */
"OS_METRICS", /* table name */
"Michael Patrick", /* author */
"OS Metrics INFORMATION_SCHEMA table", /* description */
PLUGIN_LICENSE_GPL, /* license type */
simple_table_init, /* init function */
NULL,
0x0100, /* version = 1.0 */
NULL, /* no status variables */
NULL, /* no system variables */
NULL, /* no reserved information */
0 /* no flags */
}
mysql_declare_plugin_end;

您将需要在服务器上提供MySQL源代码以及编译C代码所需的库。对我而言,我采用了手动编译插件的最基本方法,尽管我需要使用cmake对其进行更新,以便于编译。

我将文件命名为osmetricsplugin.cc。当然,在下面的示例中,您将需要定义代码放置在我放置“ {PATH_TO_YOUR_PLUGIN_CODE}”的位置的路径。

您可以使用以下命令来编译插件:

SRCBASE="../percona-server-5.7.24-27"
g++ -DMYSQL_DYNAMIC_PLUGIN -Wall -fPIC -shared \
-I/usr/include/mysql -m64 \
-I${SRCBASE}/sql \
-I${SRCBASE}/include \
-I${SRCBASE}/libbinlogevents/export \
-I${SRCBASE}/libbinlogevents/include \
-I{PATH_TO_YOUR_PLUGIN_CODE} \
-o osmetricsplugin.so osmetricsplugin.cc

如果您有兴趣了解上述操作的更多信息,请查看GitHub页面,了解我编写的插件。

编译后,您应该获得一个osmetricsplugin.so文件,该文件可以使用以下命令复制到您的MySQL插件目录中:

cp osmetricsplugin.so /usr/lib64/mysql/plugin/

安装到位后,您可以告诉MySQL使用以下命令来加载插件:

mysql> INSTALL PLUGIN OS_METRICS SONAME 'osmetricsplugin.so';

您可以验证插件是否正确加载:

mysql> SELECT * FROM information_schema.PLUGINS WHERE PLUGIN_NAME LIKE "%OS%";;
+-------------+----------------+---------------+--------------------+---------------------+--------------------+------------------------+-----------------+-------------------------------------+----------------+-------------+
| PLUGIN_NAME | PLUGIN_VERSION | PLUGIN_STATUS | PLUGIN_TYPE        | PLUGIN_TYPE_VERSION | PLUGIN_LIBRARY     | PLUGIN_LIBRARY_VERSION | PLUGIN_AUTHOR   | PLUGIN_DESCRIPTION                  | PLUGIN_LICENSE | LOAD_OPTION |
+-------------+----------------+---------------+--------------------+---------------------+-------------------+------------------------+-----------------+-------------------------------------+----------------+-------------+
| OS_METRICS  | 1.0            | ACTIVE        | INFORMATION SCHEMA | 50724.0             | osmetricsplugin.so | 1.7                    | Michael Patrick | OS Metrics INFORMATION_SCHEMA table | GPL            | ON          |
+-------------+----------------+---------------+--------------------+---------------------+--------------------+------------------------+-----------------+-------------------------------------+----------------+-------------+
1 row in set (0.00 sec)

要查询数据,请执行以下SQL命令:

mysql> SELECT * FROM information_schema.OS_METRICS;
+------------------------+-------------------+-------------------------------------------------+
| NAME                   | VALUE             | COMMENT                                         |
+------------------------+-------------------+-------------------------------------------------+
| TOTAL_RAM              |        1039118336 | Total usable main memory size                   |
| FREE_RAM               |         341049344 | Available memory size                           |
| USED_RAM               |         698068992 | Used memory size                                |
| FREE_RAM_PCT           | 32.82102966308594 | Available memory as a percentage                |
| USED_RAM_PCT           | 67.17897033691406 | Free memory as a percentage                     |
| SHARED_RAM             |                 0 | Amount of shared memory                         |
| BUFFER_RAM             |           2158592 | Memory used by buffers                          |
+------------------------+-------------------+-------------------------------------------------+
7 rows in set (0.00 sec)

插件还有很多工作要做,还有很多工作可以改进。我相信能够从MySQL内部访问系统指标是一项非常有用的功能,但我非常想听听其他人的想法。

如果有兴趣,请查看该插件的更高级版本,在这里您可以了解有关MySQL插件的更多信息。

文章来源:https://www.percona.com/blog/2020/07/08/a-simple-mysql-plugin-to-retrieve-system-metrics/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论