information_schema Introduction
information_schema介绍
information_schema数据库是MySQL自带的,里面的“表”保存着服务器当前的实时信息。它提供了访问数据库元数据的方式。元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。
在MySQL中,把information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。在INFORMATION_SCHEMA中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。
在information_schema中“创建”和维护表
最近实现的一个patch,是要在数据库中增加一个统计,统计结果以表的形式呈现,因此必须在information_schema库中增加一个表,需要了解这些表的存在形式,以及“维护数据”的方式。
本文描述information_schema库中表的存在形式,访问时的调用方法,以及在该库中增加一个表需要的修改点。
1、特殊的库、特殊的表
稍微试验下会发现,这个库与其他的数据库不同,体现为以下几点:
a)这个库中,不能创建表,所有的DDL语句都被提示”Access denied”
b)这些“表”都是只读的。
c)对应到MySQL的data目录下,没有相应的以information_schema为名的文件夹。
不仅如此,在我们深入到代码中发现,使用内置的open_table函数(sql/sql_base.cc:2531)试图打开这些表的时候,也被提示表不存在。
跟踪select * from information_schema.processlist 这样的语句发现,在查询流程中使用的表名形如 “/tmp/#sql_5c75_0”,是一个临时表。
2、临时表
实际上,整个information_schema及里面的所有表,都可以理解为视图。在需要访问到视图中数据时,通过创建临时表(sql/sql_show.cc: create_schema_table)的方式,填充数据返回给客户端。
可以看到,在没有重启server时,所有对information_schema中的表的查询请求,在查询流程中的使用的表名都是相同的。
3、源码相关—表定义
由于是临时表,也就可以理解为何在使用open_table时,会提示表不存在。要实现在information_schema库中自定义一个表的目的,就必须了解表的描述位置。
整个库的所有表定义入口为schema_tables (sql/sql_show.cc),这是一个ST_SCHEMA_TABLE的数组,每个元素用于定义一个表。在information_schema中执行show tables,即遍历该数组的所有元素得到。
如果需要新定义一个表,可以在该数组中插入一个ST_SCHEMA_TABLE的单位。注意需要同时在sql/table.h中修改enum enum_schema_tables的定义,它内部宏与schema_tables一一对应。缺少或者位置不对应将会导致MySQL运行时coredump,原因是在使用schema_tables[i]. fill_table()时,原代码中有些地方并不检验函数指针是否已定义。
ST_SCHEMA_TABLE定义了每个表的字段信息、创建形式、填充数据形式,定义在sql/table.h中。
c代码:
<span style="font-size: small;">typedef struct st_schema_table
{
const char* table_name;
ST_FIELD_INFO *fields_info;
/* Create information_schema table */
TABLE *(*create_table) (THD *thd, TABLE_LIST *table_list);
/* Fill table with data */
int (*fill_table) (THD *thd, TABLE_LIST *tables, COND *cond);
……
} ST_SCHEMA_TABLE;
</span>
说明:
1) table_name 表名
2) fields_info 字段信息数组,结构体ST_FIELD_INFO中定义了字段名、字段类型等信息。
3) create_table 表创建函数,所有的表共享一个创建函数create_schema_table
4) fill_table 内容填充函数,每个表单独定义了一个填充表内容的函数。因为表结构不同,每个表的填充函数不相同。
你可能会疑惑为什么只有填充表内容的函数,而没有修改、删除表中行的函数?原因就是information_schema中的表,不需要更新和删除操作。每一次查询,都是重新生成临时表,将内存中的信息插入到表中。
4、源码相关—表生成流程
在每次需要访问information_schema中的某个表内容时,先调用create_schema_table生成临时表,生成时需要的字段定义等信息来源于fields_info。
临时表生成后,调用fill_table指向的函数填充表内容。看一下我们常见的命令show processlist调用的fill_table函数结构。
c代码:
<span style="font-size: small;">int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
{
…….
I_List_iterator<THD> it(threads);
THD* tmp;
while ((tmp= it++))
{
/* ID */
table->field[]->store((longlong) tmp->thread_id, TRUE);
/* USER */
table->field[]->store(val, strlen(val), cs);
/* HOST */
table->field[]->store(host, strlen(host), cs);
/* DB */
table->field[]->store(tmp->db, strlen(tmp->db), cs);
…….
schema_table_store_record(thd, table);
……
}
} </span>
说明:
1) 第4行中threads是一个全局变量,记录当前的执行线程。
2) 第6行用一个循环遍历所有线程
3) 第8~16行为填充片段,略去了各种判断语句。可以清楚看到,对于每个字段,都单独进行值填充
4) 第17行的schema_table_store_record是将上面填充完成的table->field数组内容插入到临时表中
5、源码相关—新增自定义表
总结
在information_schema库中新增一个表需要的步骤如下:
1)设计好定义表的结构后,在sql/sql_show.cc中新增一个ST_FIELD_INFO mytable_fields_info结构数组,存放表信息;
2)在sql/table.h enum_schema_tables中相应增加一个宏定义SCH_MYTABLE
3)定义一个填充函数fill_schema_mytable, 此函数负责向创建好的临时表中插入数据,需要访问某个全局信息。
4)在 schema_tables数组中增加一个元素 {“table_name”, mytable_fields_info, create_schema_table, fill_schema_mytable, 0, 0, -1, -1, 0, 0}, 该元素的位置需要与第2步中增加的宏定义位置相对应。
information_schema Introduction的更多相关文章
- information_schema系列四(跟踪,列约束,表和列)
这个系列的文章主要是为了能够让自己了解MySQL5.7的一些系统表,统一做一下备注和使用,也希望分享出来让大家能够有一点点的受益. 1:KEY_COLUMN_USAGE 按照官方的解释,这个表描述的是 ...
- MySQL 5.6 Reference Manual-14.1 Introduction to InnoDB
14.1 Introduction to InnoDB 14.1.1 InnoDB as the Default MySQL Storage Engine 14.1.2 Checking InnoDB ...
- A chatroom for all! Part 1 - Introduction to Node.js(转发)
项目组用到了 Node.js,发现下面这篇文章不错.转发一下.原文地址:<原文>. ------------------------------------------- A chatro ...
- Introduction to graph theory 图论/脑网络基础
Source: Connected Brain Figure above: Bullmore E, Sporns O. Complex brain networks: graph theoretica ...
- INTRODUCTION TO BIOINFORMATICS
INTRODUCTION TO BIOINFORMATICS 这套教程源自Youtube,算得上比较完整的生物信息学领域的视频教程,授课内容完整清晰,专题化的讲座形式,细节讲解比国内的京师大 ...
- mongoDB index introduction
索引为mongoDB的查询提供了有效的解决方案,如果没有索引,mongodb必须的扫描文档集中所有记录来match查询条件的记录.然而这些扫描是没有必要,而且每一次操作mongod进程会处理大量的数据 ...
- (翻译)《Hands-on Node.js》—— Introduction
今天开始会和大熊君{{bb}}一起着手翻译node的系列外文书籍,大熊负责翻译<Node.js IN ACTION>一书,而我暂时负责翻译这本<Hands-on Node.js> ...
- Introduction of OpenCascade Foundation Classes
Introduction of OpenCascade Foundation Classes Open CASCADE基础类简介 eryar@163.com 一.简介 1. 基础类概述 Foundat ...
- 000.Introduction to ASP.NET Core--【Asp.net core 介绍】
Introduction to ASP.NET Core Asp.net core 介绍 270 of 282 people found this helpful By Daniel Roth, Ri ...
随机推荐
- 【Asp.net入门3-02】使用jQuery-jQuery 入门
下面的几小节将介绍jQuery的基础知识.如前所述,不可能仅仅通过一章的内容详细介绍jQuery, 但可以向你说明如何对HTML文档中的内容执行简单的操作,以及更重要的,如何逐步实现本书其他 部分的示 ...
- Docker入门与应用系列(四)数据卷管理
一.介绍 Docker镜像是由多个文件系统(只读层)叠加而成.当我们启动一个容器的时候,Docker会加载只读镜像层并在其上(译者注:镜像栈顶部)添加一个读写层.如果运行中的容器修改了现有的一个已经存 ...
- P4644 [Usaco2005 Dec]Cleaning Shifts 清理牛棚
P4644 [Usaco2005 Dec]Cleaning Shifts 清理牛棚 你有一段区间需要被覆盖(长度 <= 86,399) 现有 \(n \leq 10000\) 段小线段, 每段可 ...
- Hadoop生态圈-Hive快速入门篇之HQL的基础语法
Hadoop生态圈-Hive快速入门篇之HQL的基础语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客的重点是介绍Hive中常见的数据类型,DDL数据定义,DML数据操作 ...
- RAC转换传统的通信
///////////////////各种机制转信号/////////////////////////////// 1.UI事件 [self.logInButton rac_signalForCont ...
- SPI、I2C、UART、I2S、GPIO、SDIO、CAN
总线,总线,总要陷进里面.这世界上的信号都一样,但是总线却成千上万,让人头疼. 总的来说,总线有三种:内部总线.系统总线和外部总线.内部总线是微机内部各外围芯片与处理器之间的总线,用于芯片一级的互连: ...
- java 修饰符总结
java中的修饰符分为类修饰符,字段修饰符,方法修饰符.根据功能的不同,主要分为以下几种. 1.权限访问修饰符 public,protected,default,private,这四种级别 ...
- Hbase建模选择
日期 2017年3月17日 HBase建模记录 OLTP 应用场景: OLAP 应用场景: 语音分析系统的应用场景 基于HBase的建模考虑 1.话单为主来考虑hbase的rowkey的生成规则: 1 ...
- 【51nod】1766 树上的最远点对
[题意]给定n个点的树,m次求[a,b]和[c,d]中各选出一个点的最大距离.abcd是标号区间,n,m<=10^5 [算法]LCA+树的直径理论+线段树 [题解] 树的直径性质:距离树上任意点 ...
- numpy 矩阵操作
numpy 对矩阵对角线.上三角.下三角以及它们所在位置索引的提取 import numpy as np a = np.random.randint(0,10,[5,5]) print(a) # c ...