数据目录
前面我们说了mysql的安装目录,这里的数据目录可以用show variables like ‘datadir’。
数据目录存放的是什么呢,包含我们创建的数据库,表,视图和触发器等,还为了方便查找生成一些其他的额外数据。
当我们创建数据库的时候,这时候在系统目录会显示什么呢,会在目录下生成一个与数据库同名的文件,这个目录下会有一个db.opt,包含了数据库的各种属性,比方说字符集和字符集比较规则。
那么创建表的时候呢?
表名.frm:存储的是表结构文件,二进制存储的,myISAM和innodb都会有这个文件。
那么innodb除了表结构文件外,如何存储表数据呢?
在mysql5.6.6之前是默认存在系统表空间(system tablespace),他是自扩展文件,随着数据越多会越大。
在mysql5.6.6之后是默认存在独立表空表(file-per-table tablespace),每个表都有独立的表空间,意味着有两个文件,表名.frm和表名.ibd。Frm文件就是前面说的存储表结构,ibd文件就是存储索引加真实数据的。
当然这两个都可以根据参数来指定使用系统表空间还是独立表空间。随着mysql的发展还有很多其他表空间,比如undo表空间等就不一一赘述。
我们前面说过innodb索引和数据是一个b+树上,但是mySIAM不同,他所有的查询都是回表,因为目录索引叶和数据单独分开的,所以myISAM是有三个文件Test.frm、test.myd代表数据文件、test.myi代表索引文件。
我们知道mysql视图其实是虚拟的表,所以他是没有真实数据的,所以他只需要存储个表结构视图名.frm文件即可。
还有一些其他文件,mysql服务进程文件,日志文件,redo日志,undo日志等一些文件。
另外mysql系统数据库有哪些呢?
Mysql:核心数据库,存着用户账户权限等。
information_schema:维护所有其他数据库的信息,数据库,表,视图,触发器等,但不是真实数据,也可以称呼为描述的元数据。
Performance_schema:服务器运行过程的状态信息,可以说是性能监测。
Sys:通过视图的形式把information_schema和Performance_schema结合,方便程序员分析。
我们前面说了数据页(index页),页都包含file header和file trailer,前者记录一些通用信息,后者效验内存到磁盘的数据是否完整。
表空间里每个页都有自己的页号,页可以组成链表,所以不一定按照物理顺序存储,而是根据file header的头部信息上一页下一页来查找。
独立表空间结构
有区的概念(extent),因为页太多,每64个页就属于一个区,而每256个区属于一个组,第一组会记录着整个表空间一些数据,只有一个FSP_HDR类型页面。
为啥我们要有区呢,因为我们前面说了数据虽然会在b+树上,但是存储在磁盘上并不是顺序存储,两个数据之间间隔距离非常远,所以为了拉近数据过远的情况,每次数据都是在一个区内,因为查找叶子节点和非叶子节点都是范围查找,这时候如果都在一起查找明显效率会变低,所以又区把他们区分开。
区的上面就是段(segment),于是有了叶子节点段和非叶子节点段。一个聚簇索引有一个叶子节点和非叶子节点,所以有两个段。
因为每个区有2m,总不能数据每次都放在不同的区,那么就会多出很多多余的空间,这时候于是就有了碎片区(fragment)的概念。
前面三个是独立的,直属表空间管理,最后一个就属于段管理。
Free(空闲区):还没有在区用到任何页。
Free_FRAG(有剩余空间的碎片区):表示碎片区中还有可用空间。
Full_frag(没有剩余空间碎片区):都被使用。
Fseg(附属段):属于叶子段或者非叶子段。或者其他一些段。
这个结构就叫做xdes entry(extent descriptor entry)。
这个xdes entry结构里面有唯一的段id,当然为了方便查找每个区,于是肯定有上一页下一页的链表,把他们组合起来。
于是他们有了free链表,free_frag链表,full_frag链表,fseg链表。
当数据占满了32个零散的页后,就开始申请完整的区来插入数据,那么它属于哪个段呢,之前有唯一段id,可以找到。段那边又有三个链表,free链表,not_Full链表,full链表。
系统表空间结构
因为整个mysql系统只有一个系统表空间,所以会多一些结构来存储整个表空间,并且他的space_id为0。
当我们插入一条数据的时候,会效验这个数据库有没有这个表,会判断这个列是否存在等,这时候会有一些元数据以b+树的形式记录这些表。
system_table:表的一些名称。Sys_columns,sys_indexes表,sys_fields:只有聚簇索引。
但是这些表我们不能真实的访问,我们可以在前面说过的information_schema数据库里找到对应的查看表来查询这些数据,比如innodb_sys_tables就对应前面说的system_table。