一、MySQL本身的磁盘文件结构
这一节先来看一看MySQL自己的而跟存储引擎不相关的文件结构。
推荐使用MySQL官方推出的数据库可视化管理工具MySQL Workbench
,具体的下载方法可以打开MySQL Installer
查看。
打开workbench之后,填入连接对应数据库的信息,点击确认连接后可以看到对应的数据库。下图是我个人的数据库界面:
可以看到最左侧SCHEMAS
一栏,列出了所有的库sakila
sys
test
test1
world
。然后我们打开磁盘上存放这些数据库的目录:
所有的数据都是存放在MySQL主目录的Data文件夹下:
可以看到与前面数据库名字都是一一对应的。多出的两个库叫做mysql
performance_schema
下文再逐一介绍。
参数文件
MySQL启动时会去查找一个my.cnf的参数文件,用来查找数据库存放的位置和初始化参数。Windows下在主目录下叫做my.ini
的文件。
日志文件
日志文件记录了影响MySQL的各种类型活动。常见的日志文件类型有:
- 错误日志(error log)
- 二进制日志(binlog):记录了所有对数据库的更改操作,不包括
SELECT
和SHOW
这些读操作。 - 慢查询日志(slow log):这里面记录的是所有SQL语句执行时间超过一定时间阈值的数据信息,可以用来排查一些性能问题。
- 查询日志(log):记录所有对MySQL的请求信息,无论这个请求是否得到正确地执行。
pid文件
顾名思义,记录了MySQL后台服务的进程pid号。可以在Data\目录下看到后缀为 .pid的文件。
二、InnoDB存储引擎的文件结构
0x00 表 Tables
InnoDB表和.frm文件
MySQL的表数据存放在主目录下的Data\目录里面。每新建一个库即在Data\目录中新建一个同名的子目录,同时创建一个名为db.opt
的文件。这个文件中存放的是当前数据库的一些属性,比如使用了什么字符集和什么字符集比较规则。
通常情况下,InnoDB对每一个库的存储方式为File-Per-Table,就是说数据库里面每一张表的数据、索引和表的结构信息都会分开单独存放在一个 .ibd后缀的文件、一个 .frm后缀的文件,这样一张表就会有两种类型的文件,打开Data\目录就可以直观地看到。
打开其中一个库的目录可以看到大部分都是后缀为.frm和.ibd的文件,前者存储了这个库建库时的结构信息,后者存储了里面所有的表数据,里面的数据结构就是我们熟悉的B+树。对于InnoDB来说,无论是表中的数据还是索引,它最终都会以索引文件 的形式存储在磁盘上,可以说数据即索引。
0x01 索引 Indexs
MySQL官方文档中说明了数据库仅有的两种类型的索引文件:Cluster和Secondary,通俗的话说就是聚集索引和非聚集索引。
Cluster Index:每一个InnoDB表都会有一个特殊的聚集索引,每一张表只能有一个,它能够加快对表数据访问速度的作用人尽皆知。InnoDB会在以下两种情况下为每张表的某一列建立一个聚集索引:
- 定义一个
PRIMARY_KEY
或者AUTO_INCREMENT
列。 - 没有上面的两种类型的列,但是有一个被
UNIQUE
约束的列。 - 既没有主键、也没有非空且唯一的列。那么InnoDB会为这张表建立一个隐式的聚集索引,官方称他为
GEN_CLUST_INDEX
。这个索引会通过rowID
来排序。
注:显示的聚集索引里包含了rowID
信息,而隐式生成的聚集索引则不会显示这个信息。
所谓“索引即数据,数据即索引”。InnoDB中所有数据和索引在底层都是以B+树的形式存储,其实数据和索引是同一个东西。对于聚集索引而言它的叶子节点存放了完整的表数据,非聚集索引的叶子节点只存放了索引列和主键列这两种类型的数据,所以要想通过非聚集索引找到完整的记录,需要根据叶子节点上的主键列再到对应的聚集索引的叶子上找到完整的一行数据。这个过程称为“回表”操作。
B+树上的每个节点(包含非叶子节点和叶子节点)都是一个数据“页”,每一个页大小为16KB。同一层的节点前后形成一个双向列表,同一节点中的记录或数据前后形成一个单向链表。
0x02 表空间 Tablespaces
1.系统表空间
分为系统表空间和独立表空间。表空间被划分为多个连续的区,每个区默认有64个页组成,每256个区又构成一个组,每个组最开始的几个页面类型是固定的。
System Tablespace存放了上文提到的InnoDB的Data\ 目录、两次写Buffer(在Buffer中的数据写入flush到它自己的表空时,InnoDB会先写一份这个数据的副本到这个“两次写表空间”,过一段时间后调用fsync()
同步到对应的文件)、Change Buffer和Undo logs。
2.File-Per-Table Tablespaces
这个表空间已经在上文提到过。
3.General Tablespaces
4.Temporary Tablespace
5.Undo Tablespaces
这里面存储的是各种Undo Logs,它最重要的用处是InnoDB的MVCC事务控制,通过Undo Logs可以获取到最新版本的事务信息。关于MVCC事务内容将在第三篇介绍。
0x03 重做日志 Redo Log
Redo log存放的是被SQL改变了的数据和未提交的事务信息。简单来说,Redo Log的作用是用来进行InnoDB数据恢复的。注意同下文的Undo区别开来。
0x04 Undo Log
在前面表空间一节已经解释过了,这里不再赘述。