InnoDB存储引擎学习-关键特性

你未必出类拔萃,但一定与众不同

InnoDB的关键特性

插入缓冲

两次写

自适应哈希索引

异步IO

刷新邻接页

在这里插入图片描述

一.插入缓冲

1.Insert Buffer

Insert Buffer 是InnoDB存储引擎关键特性中让人激动而又兴奋的功能

Insert Buffer和数据页一样,是物理页的一个组成部分

在InnoDB存储引擎中,主键是行唯一的标识符,通常应用程序中行记录的插入顺序是按照主键递增的顺序进行插入的,因此插入聚集索引一般是按照顺序的,也就是我们定义表的时候的 AUTO_INCREMENT

一般情况下,我们对一个表数据进行插入的时候,当我们插入的那一行的主键为空的时候,因为AUTO_INCREMENT,这行的主键会进行自增,这个速度非常快,但是不可能只有一个聚集索引,更多情况下,表中可能含有多个非聚集的辅助索引,这样进行插入操作的时候,数据页的存放还是按照主键的进行顺序存放,但是对于非聚集索引叶子节点的插入不再是顺序的,就需要离散的进行访问非聚集索引页,因此B+树特性就决定了非聚集索引插入的离散性。

于是,InnoDB存储引擎开创性的设计了 Insert Buffer

对于非聚集索引的插入和更新不是直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,在的话直接插入,不在的话,先放到一个Insert Buffer对象中,如同欺骗一样,数据库的这个非聚集索引已经插入到了叶子节点,事实上则没有,而是存放到另外一个位置,然后再以一定的频率和情况进行 Insert Buffer和辅助索引页子节点的merge(合并)操作,将多个插入合并到一个操作中,大大提高了对非聚集索引插入的性能

但是Insert Buffer的使用需要满足

  • 索引是辅助索引
  • 索引不是唯一的
2.Change Buffer

InnoDB从1.0版本就开始引入了Change Buffer ,将其视为Insert Buffer的升级

从这个版本开始,Innodb存储引擎可以对DML操作-----INSERT,DELETE,UPDATE都进行缓冲,分别是 Insert Buffer,Delete Buffer,Purge Buffer

Change Buffer的适用对象也是非唯一的辅助索引

3.Insert Buffer的内部实现

Insert Buffer的数据结构是一颗B+树,全局只有一颗Insert Buffer B+树,负责对所有的表的辅助索引进行Insert Buffer,而这颗B+树存放在共享表空间,默认就是在ibdata中,因此使用独立表空间ibd文件恢复表中数据时,往往会导致CHECK TABLE失败,这是因为表中的辅助索引还存在Insert Buffer中,也就是共享表空间中,所以通过idb文件恢复后,还需要进行REPAIR TABLE操作来重建表上所有辅助索引

Insert Buffer是一颗B+树,因此由叶子节点和非叶子节点组成,非叶子节点存放的是查询的search key键值

在这里插入图片描述

4.Merge Insert Buffer

当需要实现插入记录的辅助索引不在缓冲池中,那么需要将辅助索引记录首先插入到这颗B+树中,但是Insert Buffer中的记录何时进行合并到真正的辅助索引中,就需要Merge Insert Buffer

Merge Insert Buffer可能发生在以下情况

  • 辅助索引页被读取到缓冲池中
  • Insert Buffer Bitmap页追踪到该辅助索引页已经无可用空间
  • Master Thread

第一种情况为当辅助索引页被读取到缓冲池中时,例如这在执行正常的SELECT查有绍询操作,这时需要检查Insert Buffer Bitmap页,然后确认该辅助索引页是否有记录存放在Insert Buffer B+树中。

若有,则将Insert Buffer B+树中该页的记录插人到该辅助索引页中。可以看到对该页多次的记录操作通过一次操作合并到了原有的辅助索引页中,性能会有大幅提高。

Insert Bufer Bitmap页用来追踪每个辅助索引页的可用空间,并至少有1/32页的空间。若插入辅助索引记录时检测到插人记录后可用空间会小于1/32页,则会强制进行一个合并操作,即强制读取辅助索引页,将Insert Buffer B+树中该页的记录及待插入的记录插入到辅助索引页中。这就是上述所说的第二种情况。
还有一种情况, 之前在分析Master Thread时曾讲到,在Master Thread线程中每秒或每10秒会进行一次Merge Insert Buffer 的操作,不同之处在于每次进行merge操作的页的数量不同

两次写

当发生数据库宕机的时候,假设Innodb存储引擎正在写入某个页到某个表里,而这个页只写了一部分,16KB写了4KB,就发生宕机,这就被称为部分写失效,在两次写未出现的时候,数据库就曾经以为部分写失效而导致数据丢失的情况。

也许有人会说 ,如果发生写失效,可以通过重做日志进行恢复,但是重做日志中记录的是对页的物理操作,如偏移量800,写‘aaaa’记录,如果页本身发生了损坏,这样再对其进行重做是没有意义的。

doublewrite(两次写)由两部分组成

  • 内存中的doublewrite buffer 大小为2MB
  • 物理磁盘上共享表空间的连续的128个页即2个区 大小也是2MB

在这里插入图片描述

如果操作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,InnoDB存储引擎可以从共享表空间中的doublewrite中找到该页的副本,将其复制到表空间文件,在应用重做日志

自适应哈希索引(AHI)

哈希查找的速度非常快,而b+树查找则要取决于b+树的高度,而哈希只需要一次查找就可

InnoDB存储引擎会监控对表各索引页的查询,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引,称之为自适应哈希索引(AHI).AHI通过缓冲池的B+树页构造而来,因此建立的速度很快,而且不需要为整张表建立哈希索引,自动根据访问的频率和模式来为某些热点数据建立哈希索引

  • 启用AHI后读取和写入速度可以提高2倍,辅助索引的连接速度提高5倍,数据库自优化的最好模式
  • 通过SHOW ENGINE INNODB STATUS 可以查看当前AHI使用情况

异步IO

BIO 同步阻塞

NIO 同步非阻塞

AIO 异步非阻塞

数据库系统采用AIO的方式来进行处理磁盘

  • 用户可以在发出一个IO请求后立即再发出另外一个IO请求,当全部IO请求发送完毕后,等待所有IO操作的完成 就是AIO
  • 可以进行IO Merge操作,将多个IO合成1个IO,可以提高IOPS(每秒的读写次数)的性能
  • 启动AIO 数据库的恢复速度可以提高75%

刷新邻接页

当刷新一个脏页时,InnoDB存储引擎会检测该页所在区(extent)的所有页,如果是脏页,那么一起进行刷新。这样做的好处显而易见,通过AIO可以将多个IO写入操作合并为一个IO操作,增大写入量,减少了物理写IO,故该工作机制在传统机械磁盘下有着显著的优势。

  • 是不是可能将不怎么脏的页进行了写入,而该页之后又会很快变成脏页?

  • 固态硬盘有着较高的 IOPS,是否还需要这个特性?

为此,InnoDB 存储引擎从 1.2.x 版本开始提供了参数 innodb_flush_neighbors,用来控制是否启用该特性。对于传统机械硬盘建议启用该特性,而对于固态硬盘有着超高 IOPS 性能的磁盘,则建议将该参数设置为 0、即关闭此特性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼爱吃柚子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值