(一)InnoDB体系架构

1.简介

InnoDB是事务安全的Mysql存储引擎,是OLTP应用中核心表的首选存储引擎。

2.InnoDB体系架构

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

2.1后台线程
  • Master Thread 主要负责将缓冲池中的数据异步刷新到磁盘中,除此之外还包括插入缓存、undo页的回收等
  • IO Thread负责读写IO的线程(1个insert buffer thread、1个log thread、4个read thread、4个write thread)
  • Purge Thread主要用于回收事务已经提交了的undo log (4个Purge Thread)
  • Pager Cleaner Thread是新引入的一个用于协助Master Thread刷新脏页到磁盘的线程,它可以减轻Master Thread的工作压力,减少阻塞
2.2内存
2.2.1缓冲池

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

客户端读取数据时,如果数据存在于缓冲池中,客户端就会直接读取缓冲池中的数据,否则再去磁盘中读取;对于数据库中的修改数据,首先是修改在缓冲池中的数据,然后再通过Master Thread线程刷新到磁盘上。数据从缓存池刷新回磁盘的操作并不是在每次发生更新时触发,而是通过一种称为Checkpoint的机制刷新回磁盘。理论上来说,缓冲池的内存越大越好。 InnoDB允许多个缓冲池实例,从而减少数据库内部资源的竞争,增强数据库的并发处理能力。

缓冲池中缓存的数据页类型不仅有索引页和数据页,还包括undo页、插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)、InnoDB存储的锁信息(lock info)、数据字典信息(data dictionary)等。
在这里插入图片描述

2.2.2 LRU_List、Free_List和Flush_List

LRU_LIST

缓冲池是通过LRU(最近最少使用)算法来进行管理的。即最频繁使用的页在LRU列表的前端,而最少使用的页在LRU列表的尾端。当缓冲池不能存放新读取的页时,将首先释放LRU列表中尾端的页。 InnoDB存储引擎中,缓冲池中页默认大小16KB,也通过LRU列表对缓冲池进行管理,并对传统的LRU算法做了优化。在LRU列表中加入了midpoint位置。
在这里插入图片描述

midpoint位置设置:innodb_old_block_pct 默认:37 也就是3/8位置

midpoint之前的称为:new列表,之后的称为:old列表。

问题 1:为什么不将读取的页放入到LRU列表的首部?

答:LRU列表,当不能存放新读取的页时,会释放尾部的页。若直接插入首部位置,某些SQL操作会使缓冲池中的页被刷新出去,尤其是读取大量的新页,直接插入首部,会使活跃的页逐渐被刷新出去。比如:索引或数据的全表扫描。这些页可能只在这次中用,但是活跃的页被刷新出去,下次读取该页,需要再次访问磁盘。

问题 2:解决类似全表扫描操作时,LRU列表中热点数据不被刷出?

答:设置参数:innodb_old_block_time:表示页读取到mid位置后需要等待多久才会被加入到LRU列表的热端。

​ 设置参数:innodb_old_block_pct :通过预估热点数据百分比。37–>20,降低mid位置,增加热点范围。

Free_List

LRU管理已经读取的页,数据库启动时,LRU列表是空的,没有页。此时的页都放在Free list。当需要从缓冲池中分页时,先查看Free list是否有空闲的页,若有,则从Free list中删除该页,放入到LRU列表。若没有,则根据LRU算法,释放LRU列表尾端的页,将该内存分给新页。 当页从LRU列表的old部分加入到new部分时,此时的操作称为:page made young 。 因为innodb_old_block_time设置,导致页没有从old部分移动到new部分的操作称为:page not made young。 可以通过命令SHOW ENGINE INNODB STATUS;来观察LRU列表及Free列表的使用情况和运行情况。
在这里插入图片描述

Buffer poll size 共有327679个页,即327679*16K。共5GB容量的缓冲池

Free buffers 表示当前Free列表中页的数量

Database pages 表示LRU列表中页的数量

Free buffers与Database pages 的数量之和不等于Buffer poll size 。由于部分页不需要LRU算法进行维护,所以不存在于LRU列表中。

pages made young 显示了LRU列表中页移动到前端的次数

young/s、non-youngs/s表示每秒这两类操作的次数

Buffer pool hit rate 表示缓冲池的命中率。该值通常不应该小于95%,若小于95%这种情况,用户需要观察是否是由于全表扫描引起的LRU列表被污染的问题。

Modified db pages 显示脏页的数量

问题:表页的压缩比例不同,unzip_LRU是怎么从缓冲池中分配内存的?

答:unzip_LRU也是有自己的分类的,根据1,2,4,8分类。unzip_LRU列表对不同压缩页大小的页进行分别管理。其次通过伙伴算法进行内存的分配:以4KB为例

1)检查4KB的unzip_LRU列表,是否有可用的空闲页

2)若有,直接使用

3)否则,检查8KB的unzip_LRU列表

4)若能得到空闲页,将页分成2个4KB页,存放到4KB的unzip_LRU列表中。

5)若不能得到,从LRU列表中申请16KB的页,将页分成1个8KB,2个4KB,分别放在对应的unzip_LRU中。

Flush_List

在LRU列表中的页被修改后,称该页为脏页(dirty page),即缓冲池中的页和磁盘上的页数据不一致。这时会通过checkpoint机制将脏页刷新回磁盘,而Flush list中的页即为脏页列表。

注:脏页既存在于LRU列表,也存在于Flush列表中。

LRU:用来管理缓冲池中页的可用性

Flush:用来管理将页刷新回磁盘。

2.2.3重做日志缓冲

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

日志刷新的情况有:

  • Master Thread 每一秒将重做日志缓冲刷新到日志文件;
  • 每个事务提交时会将重做日志缓冲刷新到重做日志文件;
  • 当重做日志缓冲池剩余空间小于1/2时,重做日志缓冲刷新到重做日志文件。
2.2.4额外的内存池

在InnoDB存储引擎中,对内存的管理是通过一种称为内存堆的方式进行的,当该区域的内存不够时,会从缓冲池中进行申请。例如,分配了缓冲池,但是每个缓冲池中的帧缓冲还有对性的缓冲控制对象,这些对象记录了一些注入LRU、帧、等待等信息,而这个对象的内存需要从额外内存池中申请。因此,在申请了很大的InnoDB缓冲池时,也应考虑相应地增加这个值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值