2、InnoDB架构体系

2.1、内存结构

2.1.1、buffer pool

InnoDB内存缓存区,使用空间换时间的思想,给数据做了一个缓存。把热点的数据存储在内存中,减少IO次数,提高效率。

show variables like '%innodb_buffer_pool%';

buffer pool 满了,使用LRU算法淘汰数据,剩下的就是热点数据

LRU算法
  • 热区(5/8):效率优化,对于热区前1/4的数据被使用到后,不移动到head位。超出热区数据,则被挤入到冷区。
  • 冷区(3/8)

buffer pool内存回收算法,不同于传统的LRU算法,分为热区、冷区。加载数据先到冷区,默认1s后,在此被使用到,加入到热区。

2.1.2、Change Buffer 写缓冲

Change Buffer是Buffer Pool的一部分,如果这个数据页不是唯一索引,不存在数据重复的情况,那就不需要从磁盘读取数据校验唯一性。这种情况可以先修改内存中缓冲池中的数据记录,从而提高insert、update、delete的效率。5.5版本之前inset buffer,现在也可以处理update、delete操作,所以这块区域 叫做Chang Buffer。

最后将Change Buffer数据记录到磁盘的操作叫做merge

什么时候进行merge操作呢?

  • 数据页被访问
  • 数据库shut down
  • redo log写满
  • 后台线程主动merge

调整change buffer大小,这里只能调整它占用buffer pool的比例,通过下面的参数调整

show variables like '%innodb_change_buffer_max_size%'; # 默认25%

2.1.3、Adaptive Hash Index(自适应索引)

2.1.4、Redo Log Buffer

redo log 不是每一次都写入磁盘,在buffer pool中专门留出一个区域(log buffer)用于缓存,即将要写入日志文件的数据,默认16M。

下面参数控制log buffer写入磁盘的时机:

show variables like '%innodb_flush_log_at_trx_commit%'; # 默认值是1
含义
0 (延迟写)log buffer每秒写一次log file,并且log file的flush操作同时进行。该种事务下,事务提交的时候,不会主动触发写入磁盘的操作。
1 (默认,实时写,实时刷)每次事务提交时,都会把log buffer的数据写入log file,并且刷到磁盘中。
2 (实时写,延迟刷)每次事务提交mysql都会把log buffer的数据写入log file。但是flush操作并不会同时进行。该模式下,mysql会每秒执行一次flush操作。

刷盘越快,越安全,但是也会消耗性能。

2.2、磁盘结构

2.2.1、系统表空间 System tablespaces

在默认情况下InnoDB存储引擎有一个共享表空间(对应文件/var/lib/mysql/ibdata1),也叫系统表空间。

InnoDB系统表空间包含InnoBD数据字典和双写缓冲区,Change Buffer 和Undo Logs,如果没有指定file-per-table,也包含用户创建的表和索引数据。

  • 数据字段:由内部系统组成,存储表和索引的元数据(定义信息)
  • 双写缓冲(InnoDB的一大特性)
双写缓冲

InnoBD的页和操作系统的页大小不一致,InnoDB页大小一般为16K,操作系统的页大小为4K,InnoDB的页写入到磁盘时,需要分4次写入。如果在这个4次写磁盘的过程中,出现宕机。这种情况叫做部分写失效,可能导致数据丢失。

开关参数

show variables like 'innodb_doublewrite';

虽然我们可以通过redo log进行数据恢复,但是在这个过程中,如果数据页损坏了,就不能用来恢复数据了。所以在InnoDB数据页进行写入磁盘的时候,留下一个数据页副本,保证可以正常使用redo log恢复数据,这就double write,InnoDB的双写技术。

double write由两部分组成,一部分内存中double write,一部分是磁盘上double write。因为double write是顺序写入的,不会带来很大的开销。

2.2.2、独占表空间 file-per-table tablespaces

可以通过下面开关设置,每个表独占一个表空间。

show variables like 'innodb_file_per_table'; # 默认开启

开启后,每张表都会开辟一个表空间,这个文件就是数据目录下ibd文件,存放表的数据和索引。

2.2.3、通用表空间 general tablespaces

2.2.4、临时表空间 temporary tablespaces

2.2.5、undo表空间 undo log tablespaces

2.3、后台线程

  • master thread:负责刷新缓存数据到磁盘并协调调度其他后台进程。
  • IO thread:分为change bufferlogreadwrite进程。分别用来处理change buffer、重做日志、读写请求的IO回调。
  • purge thread:用来回收undo页。
  • page cleaner thread:用来刷新脏页。