【MySQL】Insert buffer 漫谈

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:  我们知道在进行插入操作时,数据页的存放还是按主键id的执行顺序存放, 但是对于非聚集索引,叶子节点的插入不再是顺序的了。 例如,对于如下表结构进行insert操作 create table tab (    id int auto_increment,    name varchar(30),   primary key (id),   key(name)  ) engine=innodb  default charset=utf8; nanme 为非唯一字段,这时就需要离散地访问非聚集索引页,插入性能在这里变低了。
 我们知道在进行插入操作时,数据页的存放还是按主键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。

五 小结
对于廉价的机械硬盘,这个参数还是能帮助提高性能的。在SSD盛行的今天,在SSD上随机访问和顺序访问性能几乎差不多的情况下,insert buffer/change buffering特性不会带来多大的性能提升。

六 参考文章
[1]  Some little known facts about Innodb Insert Buffer 
[2] innodb-performance-change_buffering 
[3]  mysql-5-5-innodb-change-buffering 
[4]  InnoDB的Master Thread调度流程 
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
关系型数据库 MySQL 数据库
MySQL 的 change buffer 是什么?
MySQL 的 change buffer 是什么?
|
11月前
|
存储 SQL 缓存
一文带你了解MySQL之Doublewrite Buffer
上一篇文章MySQL之Adaptive Hash Index详解我们学习了InnoDB Adaptive Hash Index自适应哈希索引的工作原理。其本质是将频繁访问数据页的索引键值以“Key”放在缓存中,“Value”为该索引键值匹配完整记录所在页面(Page)的位置,通过缩短寻路路径(Search Path)从而提升MySQL查询性能的一种方式。今天我们就学习了解一下Doublewrite Buffer是什么?工作原理是怎样的?
158 0
|
11月前
|
SQL 缓存 监控
一文带你了解MySQL之Change Buffer
上一篇文章一文带你了解MySQL数据库InnoDB_Buffer_Pool(点击跳转)我们学习了InnoDB Buffer Pool的工作原理,其作用是减少MySQL读取数据时直接与磁盘打交道的次数。那么写入数据时MySQL是否做了减少IO的优化呢?答案是肯定的,就要我们深入的学习Change Buffer。
388 0
一文带你了解MySQL之Change Buffer
|
11月前
|
存储 SQL 关系型数据库
一文带你了解MySQL之Log Buffer
上一篇文章我们首次提到Redo Log的概念,Redo Log是数据库体系架构中非常重要的一个模块,它能保证数据库的Crash-safe(崩溃恢复)的能力。而今天要介绍的Log Buffer正和Redo Log息息相关、密不可分。所以我们就来一起来了解它。
361 0
|
关系型数据库 MySQL
【MySQL】tmp_table_size=64M,是干什么的?底层原理是什么?
【MySQL】tmp_table_size=64M,是干什么的?底层原理是什么?
196 0
|
存储 关系型数据库 MySQL
MySQL InnoDB的插入缓冲Insert Buffer
MySQL InnoDB的插入缓冲Insert Buffer
133 0
MySQL InnoDB的插入缓冲Insert Buffer
|
缓存 关系型数据库 MySQL
Buffer pool--mysql详解(八)
Buffer pool--mysql详解(八)
|
SQL 安全 关系型数据库
MySQL的delete应该加 limit么 ?
在业务场景要求高的数据库中,对于单条删除和更新操作,在 delete 和 update 后面加 limit 1 绝对是个好习惯。比如,在删除执行中,第一条就命中了删除行,如果 SQL 中有 limit 1;这时就 return 了,否则还会执行完全表扫描才 return。效率不言而喻。
|
消息中间件 安全 关系型数据库
MySQL-优化INSERT、UPDATE和DELETE
MySQL MyISAM INSERT UPDATE DELETE Optimizing
461 0
|
SQL 关系型数据库 MySQL
关于MYSQL flush table的作用
关于MYSQL flush table的作用水平有限,还待学习。如有错误,请指正。 先给出官方文档: ? FLUSH TABLES Closes all open tables, forces all tables in use to be closed, and flushes the query cache.
4930 0