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 buffer
、log
、read
、write
进程。分别用来处理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架构体系的主要内容,如果未能解决你的问题,请参考以下文章