简介
InnoDB作为MySQL5.5.8开始默认储存引擎,也是在此之后,大家最广泛使用的存储引擎。本文基于MySQL5.7,探究InnoDB的底层实现。
InnoDB架构
image
如上图所示,InnoDB架构由三部分组成:
- 多个后台线程,主要作用:
- 负责刷新缓冲池中的数据,保证缓冲池中的数据是最近的;
- 将已修改的数据刷新到磁盘中;
- 保证数据库发生异常的情况下,能恢复到正常状态;
- 有一块很大的内存池,主要负责:
- 维护所有进程/线程需要访问的数据结构;
- 缓存磁盘上的数据,索引等信息;
- 重做日志缓冲;
- 变更缓冲;
- 最下面的磁盘,用于存储表结构,表数据,索引,InnoDB日志等信息;
InnoDB后台线程
后台线程主要有一下几种(可以通过show engine innodb status
查看来观察InnoDB的Thread):
Master Thread
最核心的后台线程;主要作用:将缓冲池数据刷新到磁盘,保证数据一致性,包括合并插入缓冲,undo页回收等;
-
每秒触发的操作:
- 重做日志刷新到磁盘,即使这个事务还没有提交(总是);
- 合并变更缓冲(可能);
-
10秒触发的操作:
- 重做日志刷新到磁盘,即使这个事务还没有提交(总是);
- 合并变更缓冲(总是);
- 删除无用的Undo页;
IO Thread
在InnoDB存储引擎中大量使用了AIO来处理IO请求,这样可以极大提高数据库性能。而IO Thread主要负责这些IO请求的回调处理。IO Thread分为:
- write Thread:负责用户写入操作,默认有4个;可以通过
innodb_write_io_threads
参数进行配置; - read Thread:负责用户的读取操作,默认有4个;可以通过
innodb_read_io_threads
参数进行配置; - insert buffer Thread:负责插入缓冲区的合并;
- log Thread:负责将redo log刷新到磁盘;
image
Purge Thread
事务被提交后,其所使用的undo log可能不再需要了,因此需要Purge Thread来回收已经使用并分配的undo页。默认有4个,可以通过innodb_purge_threads
进行配置;
Page Cleaner Thread
主要用于脏页的刷新,主要目的是为了减轻Master Thread的工作;
注意:InnoDB提供了
innodb_io_capacity
配置参数,表示磁盘IO的吞吐量,默认是200。用于控制刷新到磁盘页的数量,因此如果用户使用了固态硬盘(SSD)等高速磁盘,完全可以调高innodb_io_capacity
,直到符合磁盘IO的吞吐量。
InnoDB内存磁盘结构
image
如图所示:可以看到,主要分为两块区域:
内存
- Buffer Pool:缓冲池,最大的一块内存区域,主要存放数据,索引,锁,数据字典等信息;
- Adaptive Hash Index:自适应哈希索引,由Buffer Pool分配空间;
- Change Buffer:变更操作缓冲(旧版叫插入缓冲),如Insert、Update、Delete;
- Log Buffer:重做日志缓冲;InnoDB存储引擎首先将重做日志信息先放到这个缓冲区,然后按一定的频率将其刷新到重做日志文件。重做日志缓冲一般不需要设置很大,可以通过
show variables like 'innodb_log_buffer_size';
查看,默认10M;
磁盘
- System Tablespace:系统表空间,文件名
ibdata1
。主要存储:- InnoDB Data Dictionary:数据字典;
- Doublewrite Buffer:双写缓冲区;
- Change Buffer:变更操作缓冲区;
- Undo Logs:undo日志;
- 共享表空间:用户在改表空间创建的表和索引等数据
- File-Per-Table Tablespace:独立表空间,文件名
.ibd
,每张表独立一个文件,通过innodb_file_per_table=ON
开启; - General Tablespace:MySQL5.7.6新增的常规表空间,通过create tablespace语法创建的共享表空间,类似系统表空间,可以存储多个schema下的多张表;
- Undo Tablespace:undo独立表空间(undo日志默认存放在系统表空间,MYSQL5.6以后开始支持undo独立表空间),由一个或多个包含undo日志的文件组成。通过
innodb_undo_tablespace
配置undo表空间的数目,innodb_undo_directory
配置存放目录; - Redo Log:重做日志区;
- Temporary Tablespace:共享临时表空间,MySQL5.7.1将临时表空间从系统表空间文件中独立出来,存储非压缩InnoDB临时表、关系对象、回滚段等数据;