简单分析mysql的InnoDB存储引擎的内存架构

文章目录

      • 读缓存(buffer pool)
      • 写缓存(change buffer)
      • redo log

简单分析mysql的InnoDB存储引擎的内存架构_第1张图片

上图是mysql官方文档中提供的InnoDB架构图,左侧是内存架构,右侧则是磁盘架构。本文主要对内存架构简单分析下,下次再说磁盘架构。

首先,我们了解一些InnoDB的基础概念:
InnoDB中数据从磁盘加载进内存的最小逻辑单位是16kb(16384个字节),叫做“页”(page)。
:就会想为什么这么定义呢?如果一次我只读1kb的数据,那IO时不就浪费了15kb的空间吗?
:这就是预读的思想,它会认为你读取这个数据后,很快就会读取这条数据后的数据了。所以就提前把这条数据相邻的数据也加载进内存

读缓存(buffer pool)

我们都知道,与磁盘的io是很消耗性能的。为了减少与磁盘的io次数。InnoDB在内存中开辟了一个buffer pool的区域(缓冲区),下次读取的时候,会先在这个缓冲区找,如果没有再去磁盘上找。修改数据的时候,会先修改内存区域中的数据,然后在mysql的后台里有一些线程专门进行批量刷新到磁盘的操作。这样就能提高我们应用的吞吐量。
查看buffer pool信息的命令:show variables like '%innodb_buffer_pool%';
简单分析mysql的InnoDB存储引擎的内存架构_第2张图片
如上图:innodb_buffer_pool_size的默认值为402653184kb也就是128mb。
:如果这个pool满了怎么办?
:它会采用一种淘汰机制:LRU算法,或许你在别的地方见过或听说过。也就是会淘汰掉最近最少使用数据。当然,mysql并不是采用普通的LRU算法,而是对它进行了升级并使用。为了解决“预读失效”,“缓冲池污染”的问题。(这里就简单的了解一下,详细的请看这篇文章)。

写缓存(change buffer)

对于读请求,缓冲池能够减少磁盘IO,提升性能。问题来了,那写请求呢?增删改的时候如果没有在buffer pool中命中,那么至少要和磁盘进行一次io,加载进内存才能操作。有没有更好的方式?
写缓存在MySQL5.5之前,叫插入缓冲(insert buffer),只针对insert做了优化;现在对delete和update也有效,叫做写缓冲(change buffer)。
在我们修改数据时,如果数据所在的页不是唯一索引,那么数据在修改的时候InnoDB不必进行唯一性检查了。这个时候根本不需要先把数据从磁盘加入到内存中,而是直接把修改的记录放在change Buffer缓冲池里,然后有后台的线程批量的刷新到磁盘。
查看change buffer信息的命令:show variables like '%innodb_change_buffer%';
在这里插入图片描述
如上图:
innodb_change_buffer_max_size:配置写缓冲的大小,占整个缓冲池的比例,默认值是25%,最大值是50%。(写多读少的业务,才需要调大这个值,读多写少的业务,25%绰绰有余)
innodb_change_buffering:配置哪些写操作启用写缓冲,可以设置成all/none/inserts/deletes等。

redo log

上面说到了,数据增删改的操作,那么问题来了。
:如果修改的数据还没刷到磁盘上,mysql就挂了怎么说,那change buffer里的数据不就玩完了吗?当然这肯定是有解决方案的。
:为了防止内存中的增删改数据丢失,InnoDB里设计了一个日志文件redo log,把这些修改写入到这个日志文件里持久化到磁盘,万一发生崩溃,重启时就会从redo log文件中读取数据,把这些数据恢复到磁盘上。这就是mysql对崩溃恢复做的处理。相当于对内存区域的持久化。
:那这写入到redo log也是与磁盘IO,那还不如直接写到数据库的磁盘类。反正都是磁盘IO凭啥写入到redo log快?
:这就要扯到随机IO和顺序IO了。
随机IO:假设我们所需要的数据是随机分散在磁盘的不同页的不同扇区中的,那么找到相应的数据需要等到磁臂(寻址作用)旋转到指定的页,然后盘片寻找到对应的扇区,才能找到我们所需要的一块数据,一次进行此过程直到找完所有数据,这个就是随机IO,读取数据速度较慢。
顺序IO:假设我们已经找到了第一块数据,并且其他所需的数据就在这一块数据后边,那么就不需要重新寻址,可以依次拿到我们所需的数据,这个就叫顺序IO。
很明显,顺序IO的效率远高于随机IO,而写入到redo log 就是顺序IO,可以延迟刷盘的时机,提高系统的吞吐量。
注意:redo log也不是发生一次sql的操作就发生IO写入一次的,它也有一个缓冲区Log Buffer,也是记录一系列操作后在通过线程刷新到redo log文件里。InnoDB中才有redo log,主要就是记录数据页的改动,redo log文件默认48Mb,超了就会覆盖,覆盖前会先刷盘。
在这里插入图片描述
<<上一篇:MYSQL开篇:mysql的体系结构

>>下一篇:InnoDB存储引擎的磁盘架构

你可能感兴趣的:(mysql)