本节介绍如何编写服务器端 INFORMATION_SCHEMA
表插件。有关实现此类插件的示例代码,请参阅 MySQL 源代码发行版的 sql/sql_show.cc
文件。您还可以查看在 InnoDB
源代码中找到的示例插件。请参阅 handler/i_s.cc
和 handler/ha_innodb.cc
文件,它们位于 InnoDB
源代码树中(位于 storage/innobase
目录中)。
要编写 INFORMATION_SCHEMA
表插件,请在插件源文件中包含以下头文件。其他 MySQL 或通用头文件也可能需要,具体取决于插件的功能和要求。
#include <sql_class.h>
#include <table.h>
这些头文件位于 MySQL 源代码发行版的 sql
目录中。它们包含 C++ 结构,因此 INFORMATION_SCHEMA
插件的源文件必须作为 C++ 代码编译。
这里开发的示例插件的源文件名为 simple_i_s_table.cc
。它创建了一个名为 SIMPLE_I_S_TABLE
的简单 INFORMATION_SCHEMA
表,该表有两个名为 NAME
和 VALUE
的列。实现该表的插件库的通用描述符如下所示
mysql_declare_plugin(simple_i_s_library)
{
MYSQL_INFORMATION_SCHEMA_PLUGIN,
&simple_table_info, /* type-specific descriptor */
"SIMPLE_I_S_TABLE", /* table name */
"Author Name", /* author */
"Simple 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;
name
成员 (SIMPLE_I_S_TABLE
) 指示在诸如 INSTALL PLUGIN
或 UNINSTALL PLUGIN
之类的语句中用于引用插件的名称。这也是 SHOW PLUGINS
或 INFORMATION_SCHEMA.PLUGINS
显示的名称。
simple_table_info
成员指向类型特定描述符,该描述符仅包含类型特定 API 版本号
static struct st_mysql_information_schema simple_table_info =
{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
通用描述符指向初始化和去初始化函数
初始化函数提供有关表结构的信息以及填充表的函数。
去初始化函数执行任何必要的清理。如果不需要清理,则此描述符成员可以为
NULL
(如所示示例)。
初始化函数应在成功时返回 0,如果发生错误则返回 1。该函数接收一个通用指针,它应将其解释为指向表结构的指针
static int 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;
}
该函数应设置表结构的这两个成员
fields_info
: 一个包含有关每个列信息的ST_FIELD_INFO
结构的数组。fill_table
: 用于填充表的函数。
fields_info
指向的数组应包含每个 INFORMATION_SCHEMA
列的元素以及终止元素。示例插件的以下 simple_table_fields
数组指示 SIMPLE_I_S_TABLE
有两列。 NAME
是字符串值,长度为 10,VALUE
是整数值,显示宽度为 20。最后一个结构标记数组的结尾。
static ST_FIELD_INFO simple_table_fields[]=
{
{"NAME", 10, MYSQL_TYPE_STRING, 0, 0 0, 0},
{"VALUE", 6, MYSQL_TYPE_LONG, 0, MY_I_S_UNSIGNED, 0, 0},
{0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0}
};
有关列信息结构的更多信息,请参阅 table.h
头文件中的 ST_FIELD_INFO
的定义。允许的 MYSQL_TYPE_
类型值是在 C API 中使用的那些值;请参阅 C API 基本数据结构。xxx
fill_table
成员应设置为填充表的函数,该函数在成功时返回 0,如果发生错误则返回 1。对于示例插件,simple_fill_table()
函数如下所示
static int simple_fill_table(THD *thd, TABLE_LIST *tables, Item *cond)
{
TABLE *table= tables->table;
table->field[0]->store("Name 1", 6, system_charset_info);
table->field[1]->store(1);
if (schema_table_store_record(thd, table))
return 1;
table->field[0]->store("Name 2", 6, system_charset_info);
table->field[1]->store(2);
if (schema_table_store_record(thd, table))
return 1;
return 0;
}
对于 INFORMATION_SCHEMA
表的每一行,此函数初始化每个列,然后调用 schema_table_store_record()
来安装该行。 store()
方法参数取决于要存储的值的类型。对于列 0 (NAME
,一个字符串),store()
获取指向字符串的指针、其长度以及有关字符串字符集的信息
store(const char *to, uint length, CHARSET_INFO *cs);
对于列 1 (VALUE
,一个整数),store()
获取值和一个标志,指示它是否为无符号数
store(longlong nr, bool unsigned_value);
有关如何填充 INFORMATION_SCHEMA
表的其他示例,请在 sql_show.cc
中搜索 schema_table_store_record()
的实例。
要编译和安装插件库文件,请使用 第 4.4.3 节“编译和安装插件库” 中的说明。要使库文件可用,请将其安装到插件目录中(由 plugin_dir
系统变量指定的目录)。
要测试插件,请安装它
mysql> INSTALL PLUGIN SIMPLE_I_S_TABLE SONAME 'simple_i_s_table.so';
验证该表是否存在
mysql> SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
-> WHERE TABLE_NAME = 'SIMPLE_I_S_TABLE';
+------------------+
| TABLE_NAME |
+------------------+
| SIMPLE_I_S_TABLE |
+------------------+
尝试从中选择
mysql> SELECT * FROM INFORMATION_SCHEMA.SIMPLE_I_S_TABLE;
+--------+-------+
| NAME | VALUE |
+--------+-------+
| Name 1 | 1 |
| Name 2 | 2 |
+--------+-------+
卸载它
mysql> UNINSTALL PLUGIN SIMPLE_I_S_TABLE;