自学内容网 自学内容网

InnoDB体系结构

Adaptive Hash Index自适应哈希索引

Innodb存储引擎会监控对表上二级索引的查找,如果发现某二级索引被频繁访问,innodb就会使用索引键的前缀建立一个哈希索引。将索引值转换为一种指针,便于直接访问,带来速度的提升。

为某个数据页建立 AHI,需要满足3个条件:

  • 某个索引树要被使用足够多次(大于17)
  • 该索引树上的某个检索条件要被经常使用(大于100)
  • 该索引树上的某个数据页要被经常使用(大于页记录数的1/16)

自适应哈希索引的优缺点:

自动优化:自适应哈希索引会自动构建和维护,不需要用户显式创建或管理。
性能提升:对于某些等值查询,自适应哈希索引可以显著减少查找时间,哈希索引,查询消耗 O(1)
降低对二级索引树的频繁访问资源。

内存消耗:自适应哈希索引完全在内存中构建,因此需要足够的内存资源。在高负载下,它可能会消耗大量的内存。
不可预测性:由于是基于运行时查询模式的,所以哈希索引的存在和组成是不可预测的。
不适用于所有查询:自适应哈希索引主要优化等值查询,对于范围查询或排序操作没有帮助。
hash自适应索引会占用innodb buffer pool

自适应哈希索引的适用场景:

等值查询频繁: 如果某个列的值经常被用作等值查询的条件,并且查询频率较高,那么 InnoDB 存储引擎可能会为该列的值构建自适应哈希索引。
热点数据访问: 对于经常被访问的热点数据,自适应哈希索引能够提供更快的查找速度,从而提高查询性能。
内存资源充足: 由于自适应哈希索引是基于内存构建的,因此需要足够的内存资源来支持其构建和维护。在内存资源充足的情况下,启用自适应哈希索引可以获得更好的性能提升。

Buffer Pool

Buffer Pool是InnoDB中的一块内存区域,默认大小128M,InnoDB为每一个缓存的数据页都创建了一个单独的区域,即控制块,内部是通过3个链表管理这些控制块的:

三个链表:

1、Free链表:管理Buffer Pool中当前未被使用的空闲页,当一个页被从LRU链表或其他链表中移除时,它会被加入到free链表中。当需要加载新的页到Buffer Pool时,InnoDB会首先从free链表中获取空闲页。如果free链表为空,InnoDB则需要从LRU链表中淘汰页来腾出空间。

2、flush链表:用于管理那些被修改过(即脏页)并且需要被刷新到磁盘上的缓存页。当一个事务提交或Buffer Pool中的空闲空间不足时,InnoDB会选择一些脏页加入到flush链表中,并在适当的时机将它们刷新到磁盘上

3、LRU链表(Least Recently Used):用于管理缓存页的访问顺序和淘汰策略,最近最少使用的页会被淘汰。它是对传统LRU链表的一个改进,它分为两部分:年轻代(New Sublist)和老年代(Old Sublist),为的是防止全表查询把整张链表都换血。当某个页的数据发生全表扫描,这个页的数据访问频率会特别高,此时会换血New Sublist,而不会对Old Sublist造成影响。

Doublewrite Buffer

当执行INSERT、UPDATE或DELETE等写操作时,MySQL首先将数据写入双写缓冲区Doublewrite Buffer,随后,双写缓冲区中的数据被同步(flush)到Doublewrite File中。这个过程是由后台线程完成的,以确保数据的持久性;一旦Doublewrite File中的数据被确认已经写入磁盘,MySQL就可以将这些数据写入实际的数据文件中。如果在写操作过程中发生故障,MySQL可以从Doublewrite File中恢复数据。由于Doublewrite File中的数据是完整的,因此可以用来修复损坏的数据文件,确保数据的完整性和一致性。

为什么要有Doublewrite Buffer?

因为存储引擎缓冲池内的数据页大小默认为16KB,而文件系统一页大小为4KB,所以在进行刷盘操作时,就有可能发生如下场景:

假设InnoDB正在写入一个页的数据,并且这个操作只完成了部分,比如只写入了50%的数据。在这种情况下,如果直接将这个不完整的数据页写入数据文件,那么数据文件就会处于一个不一致的状态。某些查询可能会读取到这个不完整的数据页,导致数据损坏或不一致。

当InnoDB写入一个数据页时,首先会将整个页写入Doublewrite Buffer。这样,即使写操作只完成了部分,Doublewrite Buffer中的数据仍然是完整的。然后,Doublewrite Buffer中的数据再被同步(flush)到实际的数据文件中。这样,即使发生故障,也可以从Doublewrite Buffer中恢复数据,确保数据的完整性和一致性。

有了Redo Log为什么还要有DoubleWrite Buffer?

redolog的设计之初,是”账本的作用“,是一种操作日志,用于MySQL异常崩溃恢复使用,是InnoDB引擎特有的日志,本质上是物理日志,记录的是“在某个数据页上做了什么修改” ,但如果数据页本身已经发生了损坏,Redo Log来恢复已经损坏的数据块是无效的,数据块的本身已经损坏,再次重做依然是一个坏块。所以此时需要一个数据块的副本来还原该损坏的数据块,再利用重做日志进行其他数据块的重做操作,这就是double write buffer的原因作用。因此,double write buffer与redolog对于容灾场景,缺一不可。


原文地址:https://blog.csdn.net/zjp_01/article/details/142997109

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!