一、什么是insert buffer

insert buffer是一种特殊的数据结构(B+ tree)并不是缓存的一部分,而是物理页,当受影响的索引页不在buffer pool时缓存 secondary index pages的变化,当buffer page读入buffer pool时,进行合并操作,这些操作可以是 INSERT, UPDATE, or DELETE operations (DML)

最开始的时候只能是insert操作,所以叫做insert buffer,现在已经改叫做change buffer了

insert buffer 只适用于 non-unique secondary indexes 也就是说只能用在非唯一的索引上,原因如下

1、primary key 是按照递增的顺序进行插入的,异常插入聚族索引一般也顺序的,非随机IO

2 写唯一索引要检查记录是不是存在,所以在修改唯一索引之前,必须把修改的记录相关的索引页读出来才知道是不是唯一、这样Insert buffer就没意义了,要读出来(随机IO)

所以只对非唯一索引有效

二、insert buffer的原理

对于为非唯一索引,辅助索引的修改操作并非实时更新索引的叶子页,而是把若干对同一页面的更新缓存起来做,合并为一次性更新操 作,减少IO,转随机IO为顺序IO,这样可以避免随机IO带来性能损耗,提高数据库的写性能

具体流程

先判断要更新的这一页在不在缓冲池中

a、若在,则直接插入;

b、若不在,则将index page 存入Insert Buffer,按照Master Thread的调度规则来合并非唯一索引和索引页中的叶子结点

Master Thread的调度规则

a、主动merger[innodb主线程定期完成,用户线程无感知]
   

主动merge通过innodb主线程(svr_master_thread)判断:若过去1s之内发生的I/O小于系统I/O能力的5%,则主动进行一次insert buffer的merge操作。merge的页面数为系统I/O能力的5%,读取采用async io模式。每10s,必定触发一次insert buffer meger操作。meger的页面数仍旧为系统 I/O能力的5%。

1)主线程发出async io请求,async读取需要被merge的索引页面
2)I/O handler 线程,在接受到完成的async I/O之后,进行merge

b 、被动merge[用户线程完成,用户能感受到meger操作带来的性能影响]

1) insert操作,导致页面空间不足,需要分裂(split)。由于insert buffer只针对单个页面,不能buffer page
split[页已经在内存里],因此引起页面的被动meger。同理,update操作导致页面空间不
足;purge导致页面为空等。总之,若当前操作引起页面split or merge,那么就会导致被动merge;

2) insert操作,由于其它各种原因,insert buffer优化返回false,需要真正读取page时,要进行被动merge。与一不同的是,页在disk上,需要读取到内存里;

3)在进行insert buffer操作,发现insert buffer太大,需要压缩insert buffer,这时需要强制被动merge,不允许 insert 操作进行。

三、insert buffer的内部实现

1、insert buffer的数据结构是一棵B+树,在MySQL4.1之前的版本中每张表都有一棵insert buffer B+树

MySQL4.1之后,全局只有一棵insert buffer B+树,负责对所有的表的辅助索引进行 insert buffer。这棵B+树存放在共享表空间中,默认也就是ibdata1中。因此,试图通过独立表空间ibd文件恢复表中数据时,往往会导致check table 失败。这是因为表的辅助索引中的数据可能还在insert buffer中,也就是共享表空间中。所以通过idb文件进行恢复后,还需要进行repair table 操作来重建表上所有的辅助索引

2、insert buffer的非叶子节点存放的是查询的search key(键值),

其构造包括三个字段:space (4 byte)+ marker(1byte) + offset(4byte) = search key (9 byte )

space表示待插入记录所在的表空间id,InnoDB中,每个表有一个唯一的space id,可以通过space id查询得知是哪张表;

marker是用来兼容老版本的insert buffer;

offset表示页所在的偏移量。

3、当一个辅助索引需要插入到页(space, offset)时,如果这个页不在缓冲池中,那么InnoDB首先根据上述规则构造一个search key,接下来查询insert buffer这棵B+树,然后再将这条记录插入到insert buffer B+树的叶子节点中

4、对于插入到insert buffer B+树叶子节点的记录,需要根据如下规则进行构造:

space | marker | offset | metadata | secondary index record

启用insert buffer索引后,辅助索引页(space、page_no)中的记录可能被插入到insert buffer B+树中,所以为了保证每次merge insert buffer页必须成功,还需要有一个特殊的页来标记每个辅助索引页(space、page_no)的可用空间,这个页的类型为insert buffer bitmap。

四、insert buffer的缺点

1、可能导致数据库宕机后实例恢复时间变长。如果应用程序执行大量的插入和更新操作,且涉及非唯一的聚集索引,一旦出现宕机,这时就有大量内存中的插入缓冲区数据没有合并至索引页中,导致实例恢复时间会很长

2、在写密集的情况下,插入缓冲会占用过多的缓冲池内存(innodb_buffer_pool),默认情况下最大可以占用1/2,这在实际应用中会带来一定的问题

3、insert buffer 无法进行控制,for different workloads and hardware configuration,特别是在SSD盛行的今天

五、查看insert buffer

mysql> show engine innodb status \G
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2,
41 inserts, 41 merged recs, 499 merges
Hash table size 3984403, node heap has 967 buffer(s)
14.66 hash searches/s, 64.65 non-hash searches/s
---
LOG
---
Log sequence number 27233311008
Log flushed up to 27233311008
Last checkpoint at 27233310593
0 pending log writes, 0 pending chkp writes
37848626 log i/o's done, 1.00 log i/o's/second
  • size: The number of pages used within the change buffer. Change buffer size is equal to seg size - (1 + free list len). The 1 + value represents the change buffer header page.

  • free list len: The number of pages free within the change buffer.代表了空闲页的数量

  • seg size: The size of the change buffer, in pages. 插入缓冲的大小为2 *16KB

  • merges: The total number of change buffer merges.表示合并次数

  • merged operations - insert: The number of inserted records merged.merged插入的记录数

  • merged operations - delete mark: The number of deleted records merged.merged删除记录数

  • merged operations - delete: The number of purge records merged.merged清除记录数

  • discarded operations - insert: The number of insert merge operations discarded.

  • discarded operations - delete mark: The number of delete merge operations discarded.

  • discarded operations - delete: The number of purge merge operations discarded.

参考

https://dev.mysql.com/doc/refman/5.5/en/innodb-standard-monitor.html

https://dev.mysql.com/doc/refman/5.5/en/innodb-insert-buffering.html

https://www.percona.com/blog/2009/01/13/some-little-known-facts-about-innodb-insert-buffer/

http://blog.itpub.net/22664653/viewspace-1163838/

【mysql】Innodb三大特性之insert buffer的更多相关文章

  1. Mysql InnoDB三大特性-- change buffer

    Mysql InnoDB三大特性-- change buffer

  2. Mysql InnoDB三大特性-- 自适应hash index

    Mysql InnoDB三大特性-- 自适应hash index

  3. InnoDB关键特性之insert buffer

    insert buffer 是InnoDB存储引擎所独有的功能.通过insert buffer,InnoDB存储引擎可以大幅度提高数据库中非唯一辅助索引的插入性能. 数据库对于自增主键值的插入是顺序的 ...

  4. innodb 关键特性(insert buffer)

    一.insert buffer 性能改善 insert buffer和数据页一样,也是物理页的一个组成部分. 在innodb存储引擎中,主键是行唯一的标识符.通常应用程序中行记录的插入顺序是按照主键递 ...

  5. Mysql InnoDB三大特性-- double write

    转自:http://www.ywnds.com/?p=8334 一.经典Partial page write问题? 介绍double write之前我们有必要了解partial page write( ...

  6. 【mysql】Innodb三大特性之adaptive hash index

    1.Adaptive Hash Indexes 定义 If a table fits almost entirely in main memory, the fastest way to perfor ...

  7. InnoDB关键特性之change buffer

    一.关于IOT:索引组织表 表在存储的时候按照主键排序进行存储,同时在主键上建立一棵树,这样就形成了一个索引组织表,一个表的存储方式以索引的方式来组织存储的. 所以,MySQL表一定要加上主键,通过主 ...

  8. 【mysql】Innodb三大特性之double write

    1.doublewrite buffer(mysql官方的介绍) InnoDB uses a novel file flush technique called doublewrite. Before ...

  9. Mysql 三大特性详解

    Mysql 三大特性详解 Mysql Innodb后台线程 工作方式 首先Mysql进程模型是单进程多线程的.所以我们通过ps查找mysqld进程是只有一个. 体系架构 InnoDB存储引擎的架构如下 ...

随机推荐

  1. Selenium2+python自动化60-异常后截图(screenshot)

    前言 在执行用例过程中由于是无人值守的,用例运行报错的时候,我们希望能对当前屏幕截图,留下证据. 在写用例的时候,最后一步是断言,可以把截图的动作放在断言这里,那么如何在断言失败后截图呢? 一.截图方 ...

  2. Appium+python自动化5-Appium Inspector

    前言    appium Inspector从入门到放弃!反正你都打开了,那就看下为什么要放弃吧! Appium Inspector是appium自带的一个元素定位工具,上一篇介绍了如何使用uiaut ...

  3. eclipse Reference 功能之——项目之间的引用

    i'm sorry, i forgot this article where i found. that it is referenced. 以前也研究过Eclipse里Web Project引用Ja ...

  4. Kafka broker配置介绍 (四)

    这部分内容对了解系统和提高软件性能都有很大的帮助,kafka官网上也给出了比较详细的配置详单,但是我们还是直接从代码来看broker到底有哪些配置需要我们去了解的,配置都有英文注释,所以每一部分是干什 ...

  5. 用java在客户端读取mongodb中的数据并发送至服务器

    使用Java自带的socket端口来实现,程序如下: Client.java package com.cn.gao; import java.net.*; import java.io.*; impo ...

  6. C语言:用二进制方式向文件读写一组数据(fread、fwrite)

    #include<stdio.h> #define SIZE 10 struct student { char name[10]; int num; int age; char addr[ ...

  7. Informatica 常用组件Expression之二 创建EXP组件

    在 Mapping Designer 中选择"转换-创建".选择表达式转换.为它输入一个名称(惯例为 EXP_TransformationName)并单击"确定" ...

  8. JavaScript前世今生

    JavaScript前世今生,HelloWorld与开发环境 JavaScript历史 大概在1992年,一家称作Nombas的公司开始开发一种叫做C--(C-minus-minus,简称Cmm)的嵌 ...

  9. JavaScript生成GUID的方法

    一.生成GUID的方法一     JScript 代码   复制 function guid() { function S4() { return (((1+Math.random())*0x1000 ...

  10. 【MySQL】MySQL-主从复制-集群方案-数据一致性问题解决方案 && MySQL备份的各种姿势

    1.写性能如何保证:分库分表 2.读性能如何保证:主从结构,实时备份 3.一致性问题怎么解决: 3.1.微博案例:Redis缓存,热数据查询走Redis,主从的延迟通过Redis消除 3.2.支付宝的 ...