mysql为了管理好页,提出了表空间的概念,表空间分为系统表空间和独立表空间两种。
一、独立表空间
系统表空间对应一个或多个系统文件,独立表空间会把数据存储在一个后缀名为ibd文件上,一个独立表空间就对应一个ibd文件。
行数据存储结构参考《mysql5.7行数据存储格式》
在分析行存储结构时,我们得出结论:一个表空间有多个段segment,每个段有多个组,每个组有256个区extent,一个区有64页是1MB。其中组一的内容是固定的,存储组的相关信息。
【区是做什么用的呢?】
mysql用区来保证一个区上面的64个页在物理上是连续的,这就有利于B+tree索引的存储结构优势还有IO上的连续读。如果数据量特别大时,mysql不会以页为单位去申请,会以区为单位去申请。
【段segment是做什么用的呢?】
区分为页节点段,叶子节点段,回滚段。段不是物理概念,是逻辑概念,mysql为了管理,延伸出了段这一概念。
二、系统表空间
系统表空间全mysql只有一个,存放整个系统相关页面,系统表空间比独立表空间存放更多系统信息。系统表空间编号最大,编号为0,只有一个,独立表空间会有多个。系统表空间的页编号从3到7会存放特有页面:
3 SYS Insert Buffer Header 存储Insert Buffer的头部信息
4 INDEX Insert Buffer Root 存储Insert Buffer的根页面
5 TRX_SYS Transction System 事务系统的相关信息
6 SYS First Rollback Segment 第一个回滚段的页面
7 SYS Data Dictionary Header 数据字典头部信息
三、innodb双写缓冲区
innodb三大特性:双写缓冲区、AHI(自适应HASH索引)、Buffer Pool。
区编号1、2是double write buffer 称为双写缓冲区(或双写机制),一个区64页是1MB,二个区就是2MB,位于系统表空间的两个区,而系统表空间存放于磁盘上,所以这里的缓冲区更多的是指磁盘上的操作。
把数据从内存刷到磁盘,称为flush, 把数据从内存刷到网卡,也称为flush,也就是把内存中的数据往IO上写,就是Flush。特殊的Flush技术就保证innodb带来了数据页的可靠格式,修改的数据在被同步到磁盘之前,会先写到双写缓冲区的位置,写完双写缓冲区之后,才会把数据写到数据页在磁盘上本来的位置,如果在写到数据页的过程中,发生了异常,innodb就会用双写缓冲区里的数据来恢复数据页。所以双写缓冲区是一个数据文件,相当于备份。
操作系统和磁盘一个扇区交互的时候是4KB,而一个页面是16KB,所以一个页面要写往磁盘至少要写4次,如果中间写入发生异常,就会造成页面不完整,而mysql的事务需要支持ACID特性:原子性、一致性,早期innodb没有引入双写缓冲区之前,这种情况就会造成页数据不完整、部分页写入问题的诟病。
如果在写入双写缓冲区时发生异常,由于B+tree索引树中存储了原始数据,那么系统会从Redo Log日志(记录了每个页面的物理操作)中读取当初双写缓冲区一开始缓存过来的脏页数据,再次恢复到双写缓冲区。
end.