美文网首页
MySQL系列之四-InnoDB-03

MySQL系列之四-InnoDB-03

作者: 花神子 | 来源:发表于2020-01-08 10:56 被阅读0次

本文主要涉及两点:

  1. InnoDB 与 MyISAM 区别;
  2. InnoDB 架构分析;
  3. InnoDB 特性;
    注 原文来自架构之路公众号

缓冲池(buffer pool)

缓存表数据与索引数据,把磁盘上的数据加载到缓冲池,避免每次访问都进行磁盘IO,起到加速访问的作用。
(1)缓冲池(buffer pool)是一种常见的降低磁盘访问的机制;
(2)缓冲池通常以页(page)为单位缓存数据;
(3)缓冲池的常见管理算法是LRU,memcache,OS,InnoDB都使用了这种算法;
(4)InnoDB对普通LRU针对以下问题进行了优化:

预读失效

由于预读(Read-Ahead),提前把页放入了缓冲池,但最终MySQL并没有从页中读取数据,称为预读失效。

  • 将缓冲池分为老生代和新生代,入缓冲池的页,优先进入老生代,页被访问,才进入新生代,以解决预读失效的问题

MySQL缓冲池污染

当某一个SQL语句,要批量扫描大量数据时,可能导致把缓冲池的所有页都替换出去,导致大量热数据被换出,MySQL性能急剧下降,这种情况叫缓冲池污染

  • 页被访问,且在老生代停留时间超过配置阈值的,才进入新生代,以解决批量数据访问,大量热数据淘汰的问题

对应InnoDB里哪些参数?

参数:innodb_buffer_pool_size
介绍:配置缓冲池的大小,在内存允许的情况下,DBA往往会建议调大这个参数,越多数据和索引放到内存里,数据库的性能会越好。

show variables  like '%innodb_buffer_pool_size%';

参数:innodb_old_blocks_pct
介绍:老生代占整个LRU链长度的比例,默认是37,即整个LRU中新生代与老生代长度比例是63:37。

  • 画外音:如果把这个参数设为100,就退化为普通LRU了。
show variables  like '%innodb_old_blocks_pct%';

参数:innodb_old_blocks_time
介绍:老生代停留时间窗口,单位是毫秒,默认是1000,即同时满足“被访问”与“在老生代停留时间超过1秒”两个条件,才会被插入到新生代头部。

show variables  like '%innodb_old_blocks_time%';

一 MySQL-写缓冲(change buffer)

原文

什么是InnoDB的写缓冲

在MySQL5.5之前,叫插入缓冲(insert buffer),只针对insert做了优化;现在对delete和update也有效,叫做写缓冲(change buffer)。

它是一种应用在非唯一普通索引页(non-unique secondary index page)不在缓冲池中,对页进行了写操作,并不会立刻将磁盘页加载到缓冲池,而仅仅记录缓冲变更(buffer changes),等未来数据被读取时,再将数据合并(merge)恢复到缓冲池中的技术。写缓冲的目的是降低写操作的磁盘IO,提升数据库性能。
画外音:R了狗了,这个句子,好长。

为什么写缓冲优化,仅适用于非唯一普通索引页呢?

  • 如果索引设置了唯一(unique)属性,在进行修改操作时,InnoDB必须进行唯一性检查。也就是说,索引页即使不在缓冲池,磁盘上的页读取无法避免(否则怎么校验是否唯一?),此时就应该直接把相应的页放入缓冲池再进行修改,而不应该再整写缓冲这个幺蛾子。

除了数据页被访问,还有哪些场景会触发刷写缓冲中的数据呢?

还有这么几种情况,会刷写缓冲中的数据:
(1)有一个后台线程,会认为数据库空闲时;
(2)数据库缓冲池不够用时;
(3)数据库正常关闭时;
(4)redo log写满时;
画外音:几乎不会出现redo log写满,此时整个数据库处于无法写入的不可用状态。

对应InnoDB里哪些参数

参数:innodb_change_buffer_max_size
介绍:配置写缓冲的大小,占整个缓冲池的比例,默认值是25%,最大值是50%。
画外音:写多读少的业务,才需要调大这个值,读多写少的业务,25%其实也多了。

参数:innodb_change_buffering
介绍:配置哪些写操作启用写缓冲,可以设置成all/none/inserts/deletes等。

二 double write buffer

MySQL的buffer一页的大小是16K,文件系统一页的大小是4K,也就是说,MySQL将buffer中一页数据刷入磁盘,要写4个文件系统里的页。(如图所示,MySQL里page=1的页,物理上对应磁盘上的1+2+3+4四个格。)


page

问题这个操作并非原子,如果执行到一半断电,会不会出现问题呢? 会,这就是所谓的“页数据损坏”

power-failure

如上图所示,MySQL内page=1的页准备刷入磁盘,才刷了3个文件系统里的页,掉电了,则会出现:重启后,page=1的页,物理上对应磁盘上的1+2+3+4四个格,数据完整性被破坏。
画外音:redo无法修复这类“页数据损坏”的异常,修复的前提是“页数据正确”并且redo日志正常。
如何解决如何解决这类“页数据损坏”的问题呢?
很容易想到的方法是,能有一个“副本”,对原来的页进行还原,这个存储“副本”的地方,就是Double Write Buffer。
Double Write Buffer,但它与传统的buffer又不同,它分为内存磁盘的两层架构。
画外音:传统的buffer,大部分是内存存储;而DWB里的数据,是需要落地的。

Double-Write-Buffer

如上图所示,当有页数据要刷盘时:(步骤2和步骤3要写2次磁盘,这就是“Double Write”的由来。)
第一步:页数据先memcopy到DWB的内存里;
第二步:DWB的内存里,会先刷到DWB的磁盘上;
第三步:DWB的内存里,再刷到数据磁盘存储上;
_画外音:_DWB由128个页构成,容量只有2M。

为什么能解决 DWB为什么能解决“页数据损坏”问题呢?

  1. 假设步骤2掉电,磁盘里依然是1+2+3+4的完整数据。
    画外音:只要有页数据完整,就能通过redo还原数据。
  2. 假如步骤3掉电,DWB里存储着完整的数据。所以,一定不会出现“页数据损坏”问题。
    画外音:写了2次,总有一个地方的数据是OK的。

网上找了一个“页数据损坏”时,MySQL重启过程利用DWB修复页数据的图。

Double-Write-Buffer-2

看到,启动过程中:

  1. InnoDB检测到上一次为异常关闭;
  2. 尝试恢复ibd数据,失败;
  3. 从DWB中恢复写了一半的页;

能够通过DWB保证页数据的完整性,但毕竟DWB要写两次磁盘,会不会导致数据库性能急剧降低呢

分析DWB执行的三个步骤:

第一步,页数据memcopy到DWB的内存,速度很快;
第二步,DWB的内存fsync刷到DWB的磁盘,属于顺序追加写,速度也很快;
第三步,刷磁盘,随机写,本来就需要进行,不属于额外操作;
另外,128页(每页16K)2M的DWB,会分两次刷入磁盘,每次最多64页,即1M的数据,执行也是非常之快的。

综上,性能会有所影响,但影响并不大。

结尾(double write buffer)

MySQL有很强的数据安全性机制

  1. 在异常崩溃时,如果不出现“页数据损坏”,能够通过redo恢复数据;
  2. 在出现“页数据损坏”时,能够通过double write buffer恢复页数据;

double write buffer

  1. 不是一个内存buffer,是一个内存/磁盘两层的结构,是InnoDB里On-Disk架构里很重要的一部分;
  2. 是一个通过写两次,保证页完整性的机制;

三 自适应哈希索引(Adaptive Hash Index, AHI)

对于InnoDB的哈希索引,确切的应该这么说:

  1. InnoDB用户无法手动创建哈希索引,这一层上说,InnoDB确实不支持哈希索引;
  2. InnoDB会自调优(self-tuning),如果判定建立自适应哈希索引(Adaptive Hash Index, AHI),能够提升查询效率,InnoDB自己会建立相关哈希索引,这一层上说,InnoDB又是支持哈希索引的;

自适应哈希索引

无论是主键索引查询还是普通索引查询在MySQL运行的过程中,如果InnoDB发现,有很多SQL存在这类很长的寻路,并且有很多SQL会命中相同的页面(page),InnoDB会在自己的内存缓冲区(Buffer)里,开辟一块区域,建立自适应哈希所有AHI,以加速查询。

为啥叫“自适应****(adaptive)****”哈希索引?
系统自己判断“应该可以加速查询”而建立的,不需要用户手动建立,故称“自适应”。

系统会不会判断失误,是不是一定能加速?
不是一定能加速,有时候会误判。
当业务场景为下面几种情况时:

  • 很多单行记录查询(例如passport,用户中心等业务)
  • 索引范围查询(此时AHI可以快速定位首行记录)
  • 所有记录内存能放得下
    AHI往往是有效的。 画外音:任何脱离业务的技术方案,都是耍流氓。

四 预读

待补充

相关文章

网友评论

      本文标题:MySQL系列之四-InnoDB-03

      本文链接:https://www.haomeiwen.com/subject/jlgjactx.html