数据目录:
Show variables like ‘datadir’;
数据目录下,用户创建的database对应一个同名的文件夹;
文件夹中有一个db.opt文件,包含db的一些属性,如字符集、比较规则等;
还有一个表名.frm文件,用来存储表结构(名称、列、数据类型、约束、索引等)
表空间:
对于InnoDB,有系统表空间和独立表空间(5.66之后):
系统表空间:ibdata,只有一份,12MB,自扩展,可自定义名称、个数、大小;
独立表空间:表名.ibd,存本表的数据;
可配置每张表使用系统还是独立表空间:alter table xx table space innodb_system/innodb_file_per_table;
对于MyIsAm:每个表分为xx.frm(结构文件)、xx.MYD(数据文件)、xx.MYI(索引文件)——相对应的,InnoDB中的数据是放在聚簇索引(主键)一起的;
文件名中的特殊字符映射成@+编码值,文件名和文件长度都受文件系统制约;
MySQL的系统数据库:mysql(记录账户、权限、存储过程、事件、日志等);
Information_schema(所有其他database信息:表、视图、触发器、列、索引等元数据);
Performance_schema(服务器状态信息、性能监控、执行语句所花时间、内存等);
在文件中的存储结构:
Fileheader结构(本页信息):
checksum、
offset(本页号)、
prev(上页号)、
next(下页号)、
LSN(日志号)、
type(页类型)、
space_id(表空间ID)、
flushLSN
数据页(索引页)根据上下页号形成双链表,用于在B树的同一层顺序查找;
MySQL以页(16K)为单位,每64页一个区(1M),每256个区一个组(256M);
分组可能只是为了便于管理,
比如第一组的前三个页面做特殊用途(第一页类型FSR_HDR,记录整个表空间的属性和本组所有区的属性;第二页类型IBUFF_BITMAP,是关于change buffer的;第三页类型INODE,用来存INODE Entry),
之后的每组前俩页面是特殊用途(第一页类型XDES,记录本组所有区的属性;第二页类型IBUFF_BITMAP);
分区是有实际作用的,每个区是物理上连续的64个页,目的是减少磁盘I/O,表示索引的B+树的所有非叶子节点构成一个段,所有叶子节点构成另一个段;即对于InnoDB的聚簇索引来说,会生成俩段,每个段以区为单位分配空间,——but这样对于小表来说很浪费,所以另外搞一个碎片区(全局):开始插数据的时候从碎片区以页为单位拿空间,,当某个段占用了32个碎片页之后,便有资格以区为单位拿空间(之前的碎片页并不会迁移到新的空间),——so,准确来讲,段是由一些碎片页(32)和一些完整的区构成的;
区类型(状态):空闲区(free)、有剩余碎片区(free_frag)、满碎片区(full_frag)、属于某个段的区(fseg);前三种不属于任何段,而直属于表空间(独立团),根据占用情况分成上面那三种类型;
XDES_Entry:记录一个区的一些属性
Segment ID:该区所属的段;
List node:包含prev page、prev offset、next page、next offset,即前后节点所在页号和偏移,从而形成双链;
State:有free、free_frag、full_frag、fseg四种状态(对应上面四种区类型);
Bitmap:表示本区的每个页面是否空闲(位图)
有了代表区的这个结构,就可以把区归类到不同的链表上:首先free、free_frag、full_frag这三种状态,通过list node连成三个链表,当段需要空间时,在只能要碎片页时就去free_frag链表头代表的区中拿页面,当此区没有空闲页时,就挂到full_frag链表上,当free_frag空了时,从free链表上取节点——怎么感觉free_frag只需要一个节点就够了,链表是啥情况?
当某段已经拿了32个碎片页后,开始为其分派完整的区(fseg状态)——应该是从free链表拿的?属于某段的区同样有free、not_full、full三种状态,做成三个链表——为啥会有free状态?即使有,一个节点也就够了吧,链表又是什么情况?
So,聚簇索引维护两个段,每个段维护3个链表。
Then,使用链表基节点list base node标识以上每一条链表(基节点包含length、first page&offset、last page&offset,即节点数和头尾指针),然后存在表空间的固定位置。
INODE Entry:表示段信息的结构——上面说过,第一组的第三页(类型INODE)用来存所有的INODE Entry
Segment ID:本段的ID;
Not full n used:not full 中已使用的页面数;
List node free、list node not full、list node full:段的三个区链表;
Magic number:本段是否初始化;
Fragment array:32个碎片页的页号
可见此结构主要管理了自己所拥有的页面。