当前位置:Gxlcms > mysql > MySQL:如何编写InformationSchemaPlugin

MySQL:如何编写InformationSchemaPlugin

时间:2021-07-01 10:21:17 帮助过:26人阅读

在mysql里面,默认会有一个information schema(以下简写为i_s)数据库,用于记录一些与元数据或表的模式相关的信息,与其他数据

印风

1. 什么是i_s plugin

在mysql里面,默认会有一个information schema(以下简写为i_s)数据库,用于记录一些与元数据或表的模式相关的信息,与其他数据库不一样,在data目录下,并没有为i_s建立文件夹,这说明,i_s并不是物理存在的,而是在需要的时候,才会临时创建。这就可以解释为什么i_s库中的表的记录总是无法删除或修改。

2.为什么使用i_s plugin

虽然i_s中定义了丰富的表,但通过i_s plugin,我们可以将其功能进行扩展,丰富其中的信息,比如,我们可以把关心信息以表的形式展现出来,可以通过引入MySQL的内核代码,来监控内核的运行状态,例如锁资源状态、线程状态、table cache状态等信息。客户端可以通过sql来过滤想要的内容,甚至,我们可以在plugin中通过cond来进行过滤,而无需在mysql层处理。

3.如何编写i_s plugin

1)之前已经介绍过的,这里不在赘述,在plugin间通用的包括:

a. plugin的声明;

b.添加系统变量(show /setvariables)

c.添加状态变量(show status)

2)初始化I_S插件

函数原型:name_init(void *p)

函数用于初始化插件,包括指定表的模式、创建表、构造表的函数指针等信息,指针p会指向一个结构体st_schema_table,如下表:

字段

类型

描述

table_name

const char*

mysql会自动对表赋予插件名,因此我们无需直接赋值

fields_info

ST_FIELD_INFO *

ST_FIELD_INFO类型的结构体数组,用于存储表的每一列的信息,如列名及类型等

create_table

TABLE *(*create_table) (THD *thd, TABLE_LIST *table_list);

函数指针,用来创建TABLE结构体,所有的i_s表基本一致,mysql会自动赋值

fill_table

int (*fill_table) (THD *thd, TABLE_LIST *tables, COND *cond);

函数指针,用于向表中填充记录

old_format

int (*old_format) (THD *thd, struct st_schema_table *schema_table);

用于支持内建i_s表的show功能,无需关注

process_table

int (*process_table) (

THD *thd, TABLE_LIST *tables, TABLE *table, bool res, LEX_STRING *db_name,

LEX_STRING *table_name);

仅用于内建i_s表

idx_field1, idx_field2

int

仅用于内建i_s表

hidden

bool

如果为true,则其中的数据只能通过show展现,由于i_s Plugin不支持show,无需关心此变量

i_s_requested_object

uint

仅用于内建i_s表

初始化的目的是为了填充结构体st_schema_table,从而确定表的定义,在查询表的时候,调用相应的函数进行记录填充。由于该结构体与内建的i_s表是公用的,因此一些字段我们可以直接忽略掉。在编写plugin的时候,我们需要填充的内容包括:

Fields_info

Fill_table

2).初始化表结构fields_info

Fields_info结构体为st_field_info

字段

类型

描述

field_name

const char*

列名,通常用大写表示

field_length

uint

当列的类型为varchar、text时表示字符数,列类型为blob时表示字节数,类型为float 或double时表示数字数,对于decima类型,值为precision*100+scale

field_type

enum enum_field_types

枚举类型,用于指定行类型,包括如下:

MYSQL_TYPE_TINY、

MYSQL_TYPE_SHORT、

MYSQL_TYPE_INT24、

MYSQL_TYPE_LONG、

MYSQL_TYPE_LONGLONG、

MYSQL_TYPE_TIME、

MYSQL_TYPE_DATE、

MYSQL_TYPE_DATETIME、MYSQL_TYPE_TIMESTAMP、MYSQL_TYPE_FLOAT、

MYSQL_TYPE_DOUBLE、MYSQL_TYPE_DECIMAL、MYSQL_TYPE_NEWDECIMAL、MYSQL_TYPE_TINY_BLOB、MYSQL_TYPE_MEDIUM_BLOB、MYSQL_TYPE_BLOB、MYSQL_TYPE_LONG_BLOB、MYSQL_TYPE_STRING,虽然类型很多,但在内置的i_s表中,只用到了MYSQL_TYPE_STRING, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG, MYSQL_TYPE_DECIMAL, MYSQL_TYPE_DATETIME这几种类型,为了避免意外的分享,我们也尽量使用这几种。

value

int

未使用

field_flags

uint

用于表示列的属性,,为MY_I_S_UNSIGNED表示列为unsigned类型,为MY_I_S_MAYBE_NULL 表示该列的值可能为NULL

这里需要注意,如果定义为MY_I_S_MAYBE_NULL类型,那么在填充表字段信息时,我们总需要首先调用:

(非空)tables->table->field[0]->set_notnull();

(为空)tables->table->field[0]->set_null();

old_name

const char*

仅用于内建的i_s表

open_method

uint

仅用于内建的i_s表

通常我们会预定义数组,以NULL列结束:

ST_FIELD_INFO is_field[] = {

{……},

……

{0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0}

}

3)fill_table()

函数原型:int fill_table(THD *thd, TABLE_LIST *tables, COND *cond);

参数描述:

参数名

类型

描述

thd

THD*

当前执行query的线程

tables

TABLE_LIST

当前query所指定的表(在i_s中的表,都是查询时才自动创建的临时表),我们需要把数据放如到tables中

人气教程排行