印风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 plugin1)之前已经介绍过的,这里不在赘述,在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_infoFields_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中 |
| cond | COND* | where条件,我们可以在函数中通过cond来过滤数据,只把需要的记录加入到临时表中。也可以不搭理,让mysql层来处理 |
为了将记录保存到i_s表中,这里不的不提到两个函数:field类的成员函数store_系列函数和schema_table_store_record(),前者用来存储数据到表结构体追踪,后者用来将一行存储好的数据放入到临时表中。store函数是Field类的方法,有5个:
| 函数 | 描述 |
| Field::store(const char *to, uint length, CHARSET_INFO *cs) | to:字符串指针;length:字符串长度cs:字符串的字符集,默认的字符集为system_charset_infobin类型为my_charset_bin、latin1类型为 my_charset_latin1,此外,我们还可以通过get_charset()、get_charset_by_name()或者get_charset_by_csname()来获得字符集信息 |
| Field::store(longlong nr, bool unsigned_val) | nr:longlong整数值unsigned_val:是否为unsigned类型 |
| Field::store(double nr) | 存储double类型 |
| Field::store_decimal(const my_decimal *d) | decimal类型 |
| Field::store_time(MYSQL_TIME *ltime, timestamp_type t_type) | 时间类型 |
其中my_declimal类型或者MYSQL_TIME等MySQL代码内特有的类型,我们都可以通过引入相应的代码来构建结构体。注意当列被声明为MY_I_S_MAYBE_NULL时,需要做一些额外的处理,见之前关于st_field_info结构体的介绍。当store数据到Field结构体后,我们还需要将其存储到表中,API函数如下:boolschema_table_store_record(THD *thd, TABLE *table);其中thd为当前线程,table为tables->table 为了包含这两个函数,我们需要引入如下头文件:#include <mysql_priv.h>
MySQL源代码:由参数query_response_time_stats想到的Python实战之Oracle数据库操作相关资讯 MySQL基础教程
- MySQL基础教程:关于varchar(N) (01月22日)
- MySQL SELECT同时UPDATE同一张表 (02/19/2013 07:20:18)
- Linux修改MySQL最大并发连接数 (02/15/2013 15:37:21)
| - 高性能MySQL(第3版) 中文PDF带目 (10/26/2014 10:03:50)
- 如何在MySQL中的获取IP地址的网段 (02/18/2013 12:23:33)
- C++和C#访问MySQL的简单代码示例 (12/21/2012 09:04:10)
|
本文评论 查看全部评论 (0)