虽然,mysql有很多有很多的引擎可供选择,但是InnoDB 引擎很好的兼顾了可靠性和并发性,因此InnoDB引擎变得越来越流行。以至于MySQL 8.0中它已经上位成为默认的引擎。

关于InnoDB的体系架构

有个名人曾经说过:“少废话,直接上东西” 。

图片来自 MySQL官网

从图中可以看出在内存中的结构分别是:Buffer Pool , Change Buffer , Adaptive Hash Index,Log Buffer 。而处于磁盘上结构分别是:Tables,Indexes,Tablespaces,Doublewrite Buffer,Redo Log,Undo Logs.

Buffer Pool

没错就是上图中最大的那一块,事实上在专用的MySQL服务器上80%的物理内存都用来分配给了Buffer Pool。Buffer Pool 主要用来存储表和索引数据,可以让Mysql直接从内存中读取所需要的数据,以便加速数据库的操作。为了方便读取操作,Buffer Pool以page为单位。为了方便管理,Buffer Pool以链表的形式的将page串联起来。由于Buffer Pool是有限的,因此已经进入Buffer Pool 中的数据将会采用LRU算法来实现数据的淘汰。不过MySql中不是简单的使用朴素LRU算法,而是针对性的进行了优化,这里暂不展开讨论。

Change Buffer

图片来自MySQL官网

二级索引不同于聚簇索引,InnoDB表中聚簇索引是组织表的依据,因此当我们对一个表发起批量修改的时候,实际上来说相当于顺序IO,但是依据主键的顺序对于二级索引进行修改,可能是随机IO。如果进行随机IO势必影响效率,因此,便有了Change buffer这个内存区域来为二级索引做一些特殊的服务。Change buffer是一个这样的内存区域,它会记录不在Buffer Pool中的二级索引页的变化。然后,当这个索引页被加载到Buffer Pool中的时候,它会和Change Buffer中的变化记录进行merge。这样便避免了随机IO,提高了效率。它可以认为是Buffer Pool的一个扩展的区域,针对二级索引的一个优化。

Adaptive Hash Index

MySQL 会监控被频繁读取的数据页,然后会把这些数据页建立Hash索引,能够加速访问。

Log Buffer

顾名思义,这是一块存储将要写入log files中的数据,因为log files是磁盘中的文件,所以按照mysql的老套路是会拯救磁盘的,Log Buffer 的使用就是存储MySQL在运行过程中产生的Log,然后再用于持久化到磁盘上。

Log Buffer的大小和其他组件一样是可以调整大小的,控制其大小的参数是
innodb_log_buffer_size,该参数默认大小是16MB。如果在应用程序中存在比较大的事务的时候,往往建议该值调大,因为这样可以避免Log Buffer空间占满后需要在事务进行中向磁盘中进行刷入,从而影响MySQL效率。

System Tablespace

系统表空间是存储doublewrite buffer 和 change buffer的地方。系统表空间同时也包含表和索引数据对于那些在系统空间中创建的表来说。

Doublewrite Buffer

Doublewrite Buffer是位于系统表空间的一块区域,这块区域是用于写入InnoDB buffer pool中的脏页的,而且写入的时机是在脏页被刷新到磁盘的合适位置之前。理论上来说,buffer pool中的脏业写入到磁盘的合适位置即可,为什么在写入合适的位置之前要先写入到这块区域呢?这是InnoDB为了实现一致性而进行的保障性策略,先将脏页大块快速顺序写入磁盘的连续区域内,如果在后续的脏业写入磁盘合适位置的过程中出现了操作系统,存储子系统或者mysqld崩溃,那么在随后的崩溃恢复过程中InnoDB便可以在Doublewrite Buffer中找到一份完好的拷贝用于恢复,从而进一步提高了系统的一致性。

虽然每次数据都要写入两次,但是Doublewrite Buffer的写入相对于真正的写入需要更少的IO操作。因为它是大块而且顺序IO写入的,所以消耗不是很大。

Redo Log

Redo Log 主要使用来crash recovery的。如果内存中的改变没有全部被刷到磁盘的时候。可以通过redo log来进行恢复。Redo Log 记录的是页真实的物理改变。Redo Log 一般有几个文件可以顺序循环写入。文件的个数可以通过参数来设置。

Undo Log

Undo Log 记录的是操作语句的逆向操作。比如现在操作对一个id=1的行进行加1操作,那么Undo Log中将会记录id=1这行减1的操作。这样的话,当事务回滚的时候,便可以借助Undo Log恢复到原来值。同时,InnoDB 引擎的mvcc中,Undo Log也可以帮助计算出每个事务中的值是多少,从而实现了一致性读。

1 对 “MySQL Innodb体系架构”的想法;

发表评论

电子邮件地址不会被公开。 必填项已用*标注