MySQL系列(二) InnoDB的应用技术概述

  • 5 缓冲池 概述

    • 缓冲池是一块内存区域,用来弥补磁盘速度读写速度过慢的影响
    • 首先将磁盘读的数据放到缓冲池中,然后进行页的判定,减少IO
    • 缓冲池页类型:索引页,数据页,undo页,插入缓冲,自适应哈希索引,锁信息等
    • 缓冲池容量满从额外缓冲池中申请
  • 6 管理缓冲池的 LRU 算法

    LRU 算法

    • 最频繁使用的页在LRU 列表的最前端,最少使用的在最后端,最后端的优先释放

    优化 LRU 算法

    • 最新访问的页放到 midpoint 中节点位置,在列表长度的5/8处
    • 中节点 之前的成为 new列表,之后的成为 old 列表。

    为什么采用优化 LRU 算法

    • 因为如果直接将读取到的页放到 LRU 列表首部,那么某些索引或数据的扫描操作可能将 LRU 列表的页大量甚至全部刷新,但是扫描的这些数据仅本次使用,并不是活跃的热点数据,所以就会导致真正的热点数据被刷新出。
    • 因此优化LRU 算法提供了一个参数,用于表示页读取到 中节点位置后,需要等待多久才会被加入到 LRU 列表的热端。
  • 7 checkpoint 技术(强制刷新脏页)

    • 应用背景

      如果每一次一个页发生变化,就立即刷新到磁盘,那么开销是非常大的。如果在从缓冲池将页的新版本刷新到磁盘时发生了宕机,那么数据就不能恢复了。

      当前事务数据库普遍采用write ahead log 策略,当事务提交时,先写重做日志,再修改页。这也是事务中持久性的要求。

    • 主要解决以下问题

      缩短数据库的恢复时间;

      缓冲池不够用时,将脏页刷新到磁盘;

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

    当数据库发生宕机时,不需要重做所有日志,因为checkpoint 之前的页都刷新到磁盘了。这样就缩短了恢复的时间。此外,当缓冲池不够用时,根据LRU 算法回溢出最少使用的页,然后对其强制执行checkpoint,刷新到磁盘。

    checkpoint 的时间,条件,脏页的选择都是非常复杂的。比如每次刷新多少页,从哪里取脏页,什么时间触发checkpoint。InnoDB 提供了两种checkpoint选择:

    • sharp checkpoint 敏捷的
    • fuzzy checkpoint 模糊的

    sharp 发生在数据库关闭时,默认将所有脏页都刷新到磁盘。

    fuzzy 发生在运行时,只刷新一部分脏页。刷新是异步的。

  • 8 插入缓冲

    在InnoDB中,主键是唯一的行标识。因此,插入聚集索引一般都是顺序的,不需要磁盘的随机读取。不过非聚集索引其插入和索引都是随机的。

    当然,B+树的特性决定了非聚集索引的插入的离散性。因为数据页所在的叶子节点是按照逻辑顺序离散存放的。

    InnoDB存储引擎开创性地设计了Insert Buffer(插入缓冲),对于非聚集索引的插入或更新操作,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若在,则插入到缓冲池中的非聚集索引页;若不在,则先放入到一个Insert Buffer对象中,好似欺骗。

    数据库这个非聚集的索引没有直接插到叶子节点,只是存放在另一个位置。然后再以一定的频率和情况进行插入 Insert Buffer 和辅助索引页子节点的merge(合并)操作,通常能将多个插入合并到一个操作中(因为在一个索引页中),这就大大提高了对于非聚集索引插入的性能。

    然而Insert Buffer的使用需要同时满足以下两个条件:

    • 索引是辅助索引(secondary index)
    • 索引不是唯一(unique)的

    当满足以上两个条件时,InnoDB存储引擎会使用 Insert Buffer,这样就能提高插入操作的性能了。不过考虑这种情况:

    • 应用程序进行大量的插入操作,这些都涉及了不唯一的非聚集索引,也就是使用了Insert Buffer。若此时MySQL数据库发生了宕机,这时势必有大量的Insert Buffer并没有合并到实际的非聚集索引中去。因此这时恢复可能需要很长的时间,在极端情况下甚至需要几个小时。
    • 辅助索引不能是唯一的,因为在插入缓冲时,数据库并不去查找索引页来判断插入的记录的唯一性。如果去查找肯定又会有离散读取的情况发生,从而导致Insert buffer 失去了意义。
  • 9 两次写

    • 作用
      • 插入缓冲带来性能上的提升。
      • 两次写 double write 带来的是数据页数据的可靠性。
    • 描述
      • 针对部分写失效:在写的过程中发生了宕机。
      • 通过日志来恢复的话,重做日志记录的是对页的物理操作,如果那个页本身发生了损坏,那么恢复就是没有意义的。因此需要一个副本,当写入失效时,先通过页的副本还原该页,这就是double write。
    • 实现
      • double write 由两部分组成
        • 一部分是内存中的 double writer buffer,大小为2M。
        • 另一部分为物理磁盘上共享表空间中连续的128 个页,即2个区, 大小同样为2M。
      • 对缓冲池中的脏页进行刷新时,并不直接写入磁盘,而是通过 double write buffer 分两次每次1M顺序的写入共享表空间的物理磁盘上,然后再同步磁盘,避免缓冲区的问题。最后再写入各个表空间文件中,此时的写入过程是离散的,因此系统压力不大。

    默认情况下所有页的刷新首先放入到 double write中。

posted @ 2019-05-04 23:17  Railg-Kai  阅读(224)  评论(0编辑  收藏  举报