Innodb数据库内存模型

故事的开篇还得要从一张Innodb内存模型图讲起:

缓冲池

     InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。通常使用缓冲池来提高数据库的整体性能。缓冲池简单说就是一块内存,通过内存的速度弥补磁盘速度较慢对数据库性能的影响。

 

     在数据库中进行读操作时,首先将从磁盘读到的页存放在缓冲池中,下一次读取相同的页时,首先判定 是否存在缓冲池中,如果有就是被命中直接读取,没有的话就从磁盘中读取。

 

       在数据库进行改操作时,首先写到缓冲池中的页(1),然后在以一定的频率刷新(2)到磁盘上。

 

        重要参数大致有:

            1> innodb_buffer_pool_size ## 缓冲区大小

            2> innodb_buffer_pool_instances  ## 缓存池实例个数,每个页根据哈希值平均分配到不同 的实例中,以减少数据库内部资源的竞争,增加数据库的并发处理能力。

 

       (1)一页默认是16KB,在分配页时采用unzip_LRU压缩内存技术。其具体实践方式是:例如当需要分配一个4KB的页时,会先找是否有4KB空闲页,如果没有再找是否有8KB的空闲页,如果没有就切分一个16KB的页为两个8KB的页,再将其中一个8KB的页切分成两个4KB的页。取其中一个4KB的页用于分配。

 

      (2)这里并不是当页发生变更时触发。而是通过一种checkpoint机制刷新到磁盘。那么什么是checkpoint机制:

          它是为了避免每出现一个脏页就就刷新一次磁盘而引入的。简单到来就是Innodb通过这个机制来决定什么时候刷新脏页,宕机之后无需重做全部日志,检查点之前的已经持久化到磁盘中了,只需重做之后的数据就行。其时机大致可以总结为:

          1> 缓冲池不够用时,将脏页缓冲到磁盘

          2> 重做日志不可用时,刷新脏页

 

LRU List、Free List和Flush List

 

       这三个list虽然表示的意义不同,但是LRU和Flush之间的数据是有部分交叉的。首先分别一句话概括这三个list是什么鬼:

       1> LRU list:存放缓存数据的页。

       2> Free list:未使用的页。

       3> Flush list:存放脏数据的页。

 

       innoDB存储引擎的缓冲池是通过LRU(Latest Recent Used)算法来进行管理的。

 

       其具体实现方式是:最频繁使用的页在LRU列表(管理已经读取到的页)的前段,最少使用的页在 LRU列表的尾端。

 

       Innodb对LRU算法做了一些优化,加入了midpoint位置。什么是midpoint:

 

       新从文件中加载到内存中的数据默认会先放入midpoint位置,而不是放入LRU列表头部。其目的是为了避免类似全标扫描(这些数据基本只是用一次)之类的操作将热点数据挤出缓存池。

 

       当需要从缓冲池中分配页时,首先从Free列表中查看是否有空闲的空闲页,若有则从Free列表中删除然后加入到LRU列表中。否则根据LRU算法,淘汰LRU列表末尾的页,将该内存空间分配给新的页。在LRU列表中的页被修改后,该页称为脏页(dirry page),这时数据库通过checkpoint机制将脏页刷回磁盘。而Flush列表中的页就是脏页列表。

 

重做日志缓冲(redo log buffer)

 

       innoDB存储引擎首先将重做日志信息放入这个缓冲区,然后按照一定的频率将其刷入重做日志文件中。重做日志缓冲区一般不需要很多,只要保证每秒产生的事务量在这个缓冲大小之内即可。可以通过innodb_log_buffer_size参数设置大小。

 

额外的内存池

 

       在innoDB存储引擎中,对内存的管理是通过一种称为内存堆(heap)的方式进行。在对一些数据结构本身的内存进行分配时,需要从额外的内 存池中进行申请,当该区域的内存不够时,需要从缓冲池中申请。

 

Innodb关键特性

       插入缓冲:物化到磁盘。优化非唯一辅助索引的插入操作,实现方式是B+树,和内存中索引页一起确保非聚集索引的性能。

       两次写:刷新脏页时,首先将脏页数据复制到内存的2M空间中,然后顺序写入磁盘,如果刷新脏页失败就拿它恢复。

       自适应hash索引:系统判断是否开启AHI,当访问模式相同时从缓冲池中的B+树构造而来。

       异步IO(AIO):多次发出IO请求,避免了中间因为等待IO完成所消耗的时间。 

       刷新邻接页:刷新一个脏页时,会检测该页所在区的所有页,如果存在脏页将一并刷新。

线程及作用

       Master Thread:1> 合并插入缓冲   2> 将日志缓冲刷新到磁盘

       IO Thread(Async IO):读写业务数据,读写插入缓冲,记录日志

       Purge Thread:回收undo页,离散读取undo页,可以进一步利用磁盘的随机读写性能 

       Page Cleaner Thread:刷新脏页

 

猜你喜欢

转载自smallbug-vip.iteye.com/blog/2288957