InnoDB架构体系

Posted fanger8848

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了InnoDB架构体系相关的知识,希望对你有一定的参考价值。

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:用来刷新脏页。

InnoDB体系架构

Reference: https://time.geekbang.org/column/article/121710

 

InnoDB体系架构

InnoDB主要包括了内存池、后台线程以及存储文件。

内存池又是由多个内存块组成的,主要包括缓存磁盘数据、redo log缓冲等;

后台线程则包括了Master Thread、IO Thread以及Purge Thread等;

由InnoDB存储引擎实现的表的存储结构文件一般包括表结构文件(.frm)、共享表空间文件(ibdata1)、独占表空间文件(ibd)以及日志文件(redo文件等)等。

技术图片

1. 内存池

如果客户端从数据库中读取数据是直接从磁盘读取的话,无疑会带来一定的性能瓶颈,缓冲池的作用就是提高整个数据库的读写性能。

客户端读取数据时,如果数据存在于缓冲池中,客户端就会直接读取缓冲池中的数据,否则再去磁盘中读取;对于数据库中的修改数据,首先是修改在缓冲池中的数据,然后再通过Master Thread线程刷新到磁盘上。

理论上来说,缓冲池的内存越大越好。

缓冲池中不仅缓存索引页和数据页,还包括了undo页,插入缓存、自适应哈希索引以及InnoDB的锁信息等等。

InnoDB允许多个缓冲池实例,从而减少数据库内部资源的竞争,增强数据库的并发处理能力。

InnoDB存储引擎会先将重做日志信息放入到缓冲区中,然后再刷新到重做日志文件中。

 

2. 后台线程

Master Thread 主要负责将缓冲池中的数据异步刷新到磁盘中,除此之外还包括插入缓存、undo页的回收等

IO Thread是负责读写IO的线程

Purge Thread主要用于回收事务已经提交了的undo log

Pager Cleaner Thread是新引入的一个用于协助Master Thread刷新脏页到磁盘的线程,它可以减轻Master Thread的工作压力,减少阻塞

 

3. 存储文件

在MySQL中建立一张表都会生成一个.frm文件,该文件是用来保存每个表的元数据信息的,主要包含表结构定义。

在InnoDB中,存储数据都是按表空间进行存放的,默认为共享表空间,存储的文件即为共享表空间文件(ibdata1)。若设置了参数innodb_file_per_table为1,则会将存储的数据、索引等信息单独存储在一个独占表空间,因此也会产生一个独占表空间文件(ibd)。

而日志文件则主要是重做日志文件,主要记录事务产生的重做日志,保证事务的一致性。

 

以上是关于InnoDB架构体系的主要内容,如果未能解决你的问题,请参考以下文章

InnoDB架构体系

InnoDB体系架构(下)

InnoDB体系架构内存

InnoDB体系架构Checkpoint技术

InnoDB体系架构(上)

InnoDB体系架构总结