4 mysql底层解析——innodb文件系统基本结构(段、簇、页面),包括连接、解析、缓存、引擎、存储等

Wesley13
• 阅读 716

上一篇,我们学习了innodb文件系统的大的框架,知道了innodb文件系统是由一些log和每个表的ibd(16K的整数倍)等文件组成的。那么这些文件,里面是怎么样的呢?

表数据文件IBD

4 mysql底层解析——innodb文件系统基本结构(段、簇、页面),包括连接、解析、缓存、引擎、存储等

上一篇我们看到了,当你新建一个库时,首先文件系统上会多一个以库名命名的文件夹。里面有ibd、frm文件,每个表对应一个ibd文件。

那么当我们新建库时,innodb做了什么呢?会初始化一个名叫ibdata1的表空间文件,用来存储所有该库的表数据,以及一些系统表,列等系统信息。还会存储将来做事务时用来保证数据完整性的回滚段数据。

上一篇我们学过了,不同的表既可以共用一个ibd文件,也可以每个表自己一个ibd文件,默认是一个表一个。

但是需要注意的是,虽然是一个表一个ibd,但这个ibd里只存储了该表的B+树数据、索引、插入缓存等信息,其余的信息如列、属性等信息还是存储在默认的ibdata1里面的。

那么ibd里到底是什么数据呢?答案就是该表的所有索引数据。

相信很多人就要迷茫了,索引不就是相当于目录吗,那每行数据跑哪里去了。要是研究过B+ tree的人应该不会迷茫,没看过的可能还以为数据库是个TXT文件呢,一行数据占文本一行。其实不是的,索引里就包含了所有数据。

如果有迷茫的,还是先看这一篇,https://blog.csdn.net/tianyaleixiaowu/article/details/94552675   或者在网上找找B+ tree原理看看,后面也会讲。B+ tree的叶子节点,就会存放所有的数据。整个表,其实就是一棵B+ tree,一个ibd就是1-N个b+ tree。N等于你的索引数量。

当你新建一个表时,你会给表创建一个主键primary Key,然后这个key就带着整行数据占据着一块空间,作为B+ tree的一个叶子节点里元素,将来要找数据,就要靠这个主键了。你可以理解为一个key-value键值对,key就是主键,value就是整行数据。如果你根本就没创建主键(不推荐),那innodb也会给你分配一个RowId来作为将来找它的主键,虽然你看不到。

这棵拥有全量数据的b+ tree,就是将来提供数据的树了,一般来说,这棵树最大也就4层,3层就能存2千万数据了,4层就很多个亿了,将来通过主键查询时,通过2-4次IO就能找到数据行。这个索引树,我们给它起了个名字——聚簇索引。

是不是终于看到面试点了,谈谈聚簇索引和二级索引(非聚簇索引)。

二级索引就是你平时创建的那些索引了,可以建多个,建在一个列或者多个列上。这些索引也会构成B+ tree,和聚簇索引的区别就是它不需要存每行的详细数据,它的叶子节点只需要存primary key或(rowId)(当然还有主键索引所在磁盘的位置PageNo)。将来能让你通过这个索引找到数据行的ID就行了。要查数据时,就根据ID去聚簇索引那棵大树去查就是了,这就是回表。

最后,索引是方便查询的,索引列的数据不适合放大的,它占用的空间一多,那么B+ tree一层中能放的个数就越少。索引列一多,插入就越慢,如果没有索引,插入一行时只需要对主键进行排序即可。如果有很多列都有索引,那么插入时,就要做很多次排序。

数据文件格式

之前已经知道了,磁盘最小单位是512字节,操作系统是4KB,mysql里最小的是page(页面)有16K。现在也知道了ibd就是放索引树的,那总不能一个树就摊在一个txt文档里吧,所以必须还要有一种文件组织结构。所有的数据都放在page里,得用一种规则来把N个page连一起,让它们形成一些关联,才能将来好查询,要先找到page,再找到page内的数据。

文件格式包括段、簇、页面。

这是一个逻辑概念,并不是一个实际存在的文件。它是构成索引的基本元素,当你创建一个B+ tree索引时,会同时创建两个段。

他们是内节点段和叶子段,内节点段用来管理B+ tree里非叶子节点的数据,叶子段用来管理叶子节点的数据。叶子和非叶子应该知道是什么了,里面存的东西都是什么应该也清楚,如果还不知道,建议切蛋自尽。

内节点段负责管理那些非叶子节点的分裂啊、增长啊、删除啊,叶子端就负责行数据的相关动作。

这玩意比段要低一级,段是个逻辑概念,段内部就是多个簇(Extent)组成的。一个簇是物理上连续分配的一段空间,(连续很重要)。每个段至少会有一个簇,在创建一个段时就会创建一个默认的簇,一个簇的大小默认是64个Page(页面),所以一个簇就是64*16K的硬盘空间。

当往段里写入数据后,就是往簇里写数据,簇可是硬盘空间。当一个簇已经放不下时,就会再来一个簇,等于又多了一块64*16K的连续硬盘空间。段可以无限大,注意,每个簇是一块连续的硬盘空间,但多个簇之间可不是连续的。

同样,两个段之间,在硬盘上也没有什么关系。

页面

每个簇里有64个页面,都会进行编号,页面就是最小的存储单元了。这个簇里的每个页面都是连续的一段空间,往里面写数据时,就会一个页面一个页面的写入,一个页面占满了,就去下一个页面。一个页面16K,放主键如int型能放好几千,放一行数据,譬如1K一行,能放十几行。这里就需要注意了,一行数据尽量不要过大,一旦跨page了,就会对性能产生影响。本来一个page就能查出来,结果每次要查2个page,那性能就丢了一倍。

4 mysql底层解析——innodb文件系统基本结构(段、簇、页面),包括连接、解析、缓存、引擎、存储等

其他

一个表,占用一个表空间,创建一个表空间时,至少有一个文件(0号文件),这个文件的第一个页面page,page_no=0,这个page中存储了这个表空间中,所有段、簇、页管理的入口。里面有如下信息:

FSP_SPACE_ID:表空间的唯一ID号

FSP_SIZE:当前表空间的总页面数

FSP_FREE:一个链表(存储了所有空闲簇(空闲的、新分配的),反正就是所有暂时没用的簇的指针,不用了就放这个链表,要用时,就从这里拿)

FSP_FREE_FRAG:上面那个是完全空闲的簇,这个里面是半满的,里面不是全空,是有部分页面被占用的

FSP_FULL_FRAG:所有被占满了的簇的链表头指针

等等,还有很多信息。目的当然就是将各个空间都管理起来,满的空的,等等各种指针,将来好做数据的增删改查。

下一篇,就进入到b+ tree内部,和每个page内部,去看看里面到底是什么。

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
InnoDB存储引擎
InnoDB存储引擎InnodbBufferPool(缓存池)InnodbBufferPool的概念InnoDB的BufferPool主要用于缓存用户表和索引数据的数据页面。它是一块连续的内存,通过一定的算法对这块缓存做有效的管理。官方文档建议,如果此台服务器为MySQL专用数据库服务
Wesley13 Wesley13
3年前
2 mysql底层解析——表对象缓存,包括连接、解析、缓存、引擎、存储等
学习了mysql的连接层之后(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Ftianyalei.blog.csdn.net%2Farticle%2Fdetails%2F99958892),要来看一下mysql的server层了。这一层聚集了mysql的最多的逻辑,包括了请求解析、查询缓
Wesley13 Wesley13
3年前
mysql更改表引擎INNODB为MyISAM的方法总结
常见的mysql表引擎有INNODB和MyISAM,主要的区别是INNODB适合频繁写数据库(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.111cn.net%2Fdatabase%2Fdatabase.html)操作,MyISAM适合读取数据库的情况多一点,如何把表引擎INNO
Wesley13 Wesley13
3年前
Mysql MyISAM与InnoDB 表锁行锁以及分库分表优化
<divclass'title\_1'一、两种存储引擎:MyISAM与InnoDB区别与作用</div1.count运算上的区别:因为MyISAM缓存有表metadata(行数等),因此在做COUNT(\)时对于一个结构很好的查询是不需要消耗多少资源的。而对于InnoDB来说,则没有这种缓存。2.是否支持事务和崩溃后
Wesley13 Wesley13
3年前
018:InnoDB 存储引擎、表空间
\TOC\一.InnoDB存储引擎1\.InnoDB的历史年份事件备注1995由HeikkiTuuri创建InnobaseOy公司,并开发InnoDB存储引擎Innobase开始做的是数据库,希望卖掉该公司1996MySQL1.0发布
Wesley13 Wesley13
3年前
RDS MySQL InnoDB 锁等待和锁等待超时的处理
https://help.aliyun.com/knowledge\_detail/41705.html1\.Innodb引擎表行锁等待和等待超时发生的场景(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fhelp.aliyun.com%2Fknowledge_detail%2F
Wesley13 Wesley13
3年前
MySQL数据库InnoDB存储引擎Log漫游(1)
作者:宋利兵来源:MySQL代码研究(mysqlcode)0、导读本文介绍了InnoDB引擎如何利用UndoLog和RedoLog来保证事务的原子性、持久性原理,以及InnoDB引擎实现UndoLog和RedoLog的基本思路。00–UndoLogUndoLog是为了实现事务的原子性,
Wesley13 Wesley13
3年前
mysql经典面试题
1、MySQL的复制原理以及流程基本原理流程,3个线程以及之间的关联;2、MySQL中myisam与innodb的区别,至少5点(1)、问5点不同;(2)、innodb引擎的4大特性(3)、2者selectcount(\)哪个更快,为什么3、MySQL中varchar与char的区别以及varchar(50)中的50代表的涵义(
Wesley13 Wesley13
3年前
5 mysql底层解析——b+ tree和每个page存储结构,包括连接、解析、缓存、引擎、存储等
上一篇(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fblog.csdn.net%2Ftianyaleixiaowu%2Farticle%2Fdetails%2F100079700),我们学习了innodb文件系统内部大的存储结构,包括段(segment),簇(extent),页(pa
Wesley13 Wesley13
3年前
3 mysql底层解析——innodb文件系统初步入门,包括连接、解析、缓存、引擎、存储等
上一篇我们学习了server层对于表对象缓存(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fblog.csdn.net%2Ftianyaleixiaowu%2Farticle%2Fdetails%2F99971213)的处理,表对象获取到之后,通过handler才具备了与存储引擎交互的