InnoDB 关键特性

  1. insert buffer是对写索引做了优化, 而索引具体起作用是在读数据的时候

1.插入缓冲 (Insert Buffer)

insert buffer是和数据页平级的一个物理页

innodb_memory_overview.png
  1. 触发insert buffer
  2. 生成insert buffer
  3. 合并insert buffer中的数据到索引页

1.1 触发insert buffer的条件

  1. 索引是secondary index
  2. 索引不是unique的 (不需要再去判断是否是unique, 不然又多一次IO)
  3. 插入数据的时候, 才会往这里添加数据

1.2 insert buffer的具体生成过程

对于非primary index的插入或更新操作, 并不是每次直接插入到索引页, 而是:

  1. 判断插入的非primary index索引页是否在缓冲池中, 如果是则直接插入
  2. 如果不是, 先放入一个insert buffer对象中
  3. 再以一定的频率进行insert buffer和secondary index索引页子节点的merge (性能提升在于, 此时通常可以将多个插入合并到一个操作中, 大大提升了插入性能)

1.3 insert buffer的扩展

InnoDB对于DML操作(insert, delete, update) 都有对应的buffer

这些buffer统称为change buffer

1.4 相关配置参数

参数 备注
ibuf_pool_size_per_max_size 占用缓冲区的大小 (在写密集的情况下)
innodb_change_buffering 表示要启用的buffer类型 (默认为all)
ibuf_change_buffer_max_size 类似ibuf_pool_size_per_max_size, 新版参数

1.5 insert buffer具体数据结构

insert buffer 是一个B+树, 所以它的数据都是存在叶子结点的

非叶子结点有如下字段:

字段 含义 占用字节数
space 表空间id 4
marker 兼容老版insert buffer 1
offset 所在页的偏移量 4

叶子结点有如下额外字段(包含了以上3个字段):

字段 含义 占用字节数
metadata 保存进入insert buffer的顺序 4
secondary index record 具体的索引数据

1.6 合并insert buffer

合并触发的条件:

  1. 辅助索引页被读取到缓冲池中 (例如: 在执行select 操作的时候, 需要判断是否有记录存放在insert buffer中)
  2. Insert Buffer Bitmap页追踪到该辅助索引页已无可用空间时
  3. Master Thread

insert buffer要合并到索引页的时候, 需要确保合并进去之后不会造成页的分裂和合并, 所以需要一个额外的结构区记录每个索引页的大小, 这个结构叫做 Insert Buffer Bitmap也是以页来存储的

2. 两次写(Double Write)

保证了数据页的可靠性

写失效:

当某个页只写了一部分, 因为一个页为16K, 只写了4K就发生了宕机

为什么没有double write的话, 数据页会存在不可靠的问题?

用redo log在恢复数据的时候, 如果页本身损坏了, 再对其做redo就没有意义了

什么是double write:

当写入失效发生时, 先通过页的副本来还原页, 再进行redo

double_write_fra.png
  1. 有数据写入了缓冲区, 出现了脏页
  2. memcpy 脏页复制到内存中的doublewrite buffer
  3. doublewrite buffer写入共享表空间的物理磁盘, 再调用fsync 同步磁盘, 避免缓冲写带来的问题, 因为是顺序写开销不大
  4. 写入各个表空间文件, 离散写, 开销较大

通过doublewrite恢复数据流程:

  1. 从共享表空间中找到该页的一个副本
  2. 将1中的副本拷贝到表空间文件
  3. 应用redo log

性能指标:

innodb_dblwr_pages_written:innodb_dblwr_writes 远小于 64:1

则说明系统写入压力不大

3. 自适应hash index (AHI)

AHI是从哪里构建的

AHI 是通过缓冲池的B+树页而构建的, 并且不需要对整张表构建hash index

AHI的触发条件

InnoDB监控对表上索引的查询, 发现创建AHI可以提升查询速度

AHI的建立要求

对该页的连续访问模式必须是一样的

访问模式 (对于(a,b) 这样的联合索引页, 其访问模式可用是如下情况):

  1. where a=xxx
  2. where a=xxx and b=xxx

如果以上两种情况交替查询AHI也不会建立

监控指标:

show engine innodb status;

1640.60 hash searches/s, 3709.66 non-hash searches/s

4. 异步IO

与异步IO区别的是同步IO,即多个IO操作是顺序执行的, 时间上不能有重叠

异步IO的优势:

  1. 异步IO表示, 虽然IO的请求可用顺序发出, 但执行上时间是可以重叠的, 这样可以提升效率
  2. IO Merge, 即多个IO合并为1个IO, 可以提高IOPS性能

IO Merge示例:

用户访问 (space, page_no)为: (8, 6), (8, 7), (8, 8), AIO会发送一个IO请求, 从(8,6)开始, 读取48KB的页

监控:

iostat, 查看 rrqm/s 和 wrqm/s

5. 刷新邻接页

当刷新一个脏页时, InnoDB会检测该页所在的区, 并将该区下所有的脏页一起刷新, 此时AIO可以发挥作用

  1. 页更容易变脏: 一个不太脏的页被写入了, 该页之后很快会变成一个脏页
  2. 固态硬盘有较高的IOPS, 是否需要改特性: 不需要

ref:

  1. InnoDB存储引擎
  2. https://www.cnblogs.com/zuoxingyu/p/3761461.html
  3. https://mysqlserverteam.com/the-innodb-change-buffer/
  4. https://stackoverflow.com/questions/2340610/difference-between-fflush-and-fsync

你可能感兴趣的:(InnoDB 关键特性)