怎么理解MySQL的Insert buffer

55次阅读
没有评论

共计 2551 个字符,预计需要花费 7 分钟才能阅读完成。

本篇内容介绍了“怎么理解 MySQL 的 Insert buffer”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让丸趣 TV 小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

  我们知道在进行插入操作时,数据页的存放还是按主键 id 的执行顺序存放,但是对于非聚集索引,叶子节点的插入不再是顺序的了。
例如, 对于如下表结构进行 insert 操作
create table tab ( 
  id int auto_increment, 
  name varchar(30),
  primary key (id),
  key(name)
 ) engine=innodb  default charset=utf8;
nanme 为非唯一字段,这时就需要离散地访问非聚集索引页,插入性能在这里变低了。然而这并不是这个 name 字段上索引的错误,因为 B + 树的特性决定了非聚集索引插入的离散性。
为了解决非聚族索引的随机写性能差,InnoDB 存储引擎开发了 innsert-buffer pool (5.5 中做了加强, 称之为 change buffer pool)

一 什么是 innsert-buffer pool
innodb 使用 insert buffer 欺骗 数据库: 对于为非唯一索引,辅助索引的修改操作并非实时更新索引的叶子页, 而是把若干对同一页面的更新缓存起来做合并为一次性更新操作, 转化随机 IO 为顺序 IO, 这样可以避免随机 IO 带来性能损耗,提高数据库的写性能。
1.1 原理:
   a 先判断要更新的这一页在不在内存中。
   b 如果不在, 则读取 index page 存入 Insert Buffer,按照 Master Thread 的调度规则来合并非唯一索引和索引页中的叶子结点.

1.2 Master Thread 的调度规则
  a 主动 merger[innodb 主线程定期完成,用户线程无感知]
    主动 merger:
    原理: 主动 merge 通过 innodb 主线程(svr_master_thread)判断:若过去 1s 之内发生的 I / O 小于系统 I / O 能力的 5%,
        则主动进行一次 insert buffer 的 meger 操作。meger 的页面数为系统 I / O 能力的 5%,读取采用 async io 模式。
        每 10s, 必定触发一次 insert buffer meger 操作。meger 的页面数仍旧为系统 I/ O 能力的 5%。
    步骤:
        1. 主线程发出 async io 请求,async 读取需要被 meger 的索引页面
       2.I/O handler 线程,在接受到完成的 async I/ O 之后,进行 merger
  b 被动 merge[用户线程完成,用户能感受到 meger 操作带来的性能影响]
    被动 merge:
      情况一:
      insert 操作,导致页面空间不足,需要分裂(split)。由于 insert buffer 只针对单个页面,不能 buffer page split[页已经在内存里],因此引起页面的被动 meger。同理,update 操作导致页面空间不 足;purge 导致页面为空等。总之: 若   当前操作引起页面 split or merge, 那么就会导致被动 merge。
      情况二:
     insert 操作,由于其它各种原因,insert buffer 优化返回 false,需要真正读取 page 时,要进行被动 merge。与一不同的是,页在 disk 上,需要读取到内存里。
      情况三:
      在进行 insert buffer 操作,发现 insert buffer 太大,需要压缩 insert buffer, 这时需要强制被动 merge, 不允许 insert 操作进行。

二 为什么要求是非唯一索引呢?
因为
  1 主键是行唯一的标示符, 当 app 写入行时,是按照主键递增的顺序进行插入的,异常插入聚族索引一般也顺序的,不需要随机 IO。
  2 写唯一索引要检查记录是不是存在,所以在修改唯一索引之前, 必须把修改的记录相关的索引页读出来才知道是不是唯一, 这样 Insert buffer 就没意义了,反正要读出来(读带来随机 IO),所以只对非唯一索引有效。

三 如何查看 insert buffer  
我们可以通过 show engine innodb status \G 来查看插入缓冲的信息
————————————-
INSERT BUFFER AND ADAPTIVE HASH INDEX
————————————-
Ibuf: size 1, free list len 0, seg size 2, 2920 merges
merged operations:
 insert 23858, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0

seg size 显示了当前插入缓冲的大小为 2 *16KB,大约为 32KB,free list len 代表了空闲列表的长度,size 代表了已经合并记录页的数量。merges 表示合并次数。
merged operations:
Inserts 代表插入的记录数,delete mark delete 次数均为 0.

四 insert buffer 增强之 change buffering
   change buffering 是 MySQL5.5 加入的新特性,change buffering 是 insert buffer 的加强,insert buffer 只针对 insert 有效,change buffering 对 insert、delete、update(delete+insert)、purge 都有效。当修改一个索引块 (secondary index) 时的数据时,索引块在 buffter pool 中不存在,修改信息就会被 cache 在 change buffer 中,当通过索引扫描把需要的索引块读取到 buffer pool 时,会和 change buffer 中修改信息合并,再择机写回 disk。目的还是为了减少随机 IO 带来性能损耗,说明白了:把随机 IO 尽量变成顺序 IO。

“怎么理解 MySQL 的 Insert buffer”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注丸趣 TV 网站,丸趣 TV 小编将为大家输出更多高质量的实用文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-19发表,共计2551字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)