InnoDB的关键特性-插入缓存,两次写,自适应hash索引
InnoDB存储引擎的关键特性包括插入缓冲、两次写(double write)、自适应哈希索引(adaptive hash index)。这些特性为InnoDB存储引擎带来了更好的性能和更高的可靠性。
插入缓冲
插入缓冲是InnoDB存储引擎关键特性中最令人激动的。不过,这个名字可能会让人认为插入缓冲是缓冲池中的一个部分。其实不然,InnoDB缓冲池中有Insert Buffer信息固然不错,但是Insert Buffer和数据页一样,也是物理页的一个组成部分。
主键是行唯一的标识符,在应用程序中行记录的插入顺序是按照主键递增的顺序进行插入的。因此,插入聚集索引一般是顺序的,不需要磁盘的随机读取。
比如说我们按下列SQL定义的表:create table t(id int auto_increment,name varchar(30),primary key(id));
id列是自增长的,这意味着当执行插入操作时,id列会自动增长,页中的行记录按id执行顺序存放。一般情况下,不需要随机读取另一页执行记录的存放。因此,在这样的情况下,插入操作一般很快就能完成。但是,不可能每张表上只有一个聚集索引,在更多的情况下,一张表上有多个非聚集的辅助索引(secondary index)。比如,我们还需要按照name这个字段进行查找,并且name这个字段不是唯一的。
表是按如下的SQL语句定义的:create table t (id int auto_increment,name varchar(30),primary key(id),key(name));
将多个插入合并到一个操作中(因为在一个索引页中),这就大大提高了对非聚集索引执行插入和修改操作的性能。
插入缓冲的使用需要满足以下两个条件:
- 索引是辅助索引。
- 索引不是唯一的。
当满足以上两个条件时,InnoDB存储引擎会使用插入缓冲,这样就能提高性能了。不过考虑一种情况,应用程序执行大量的插入和更新操作,这些操作都涉及了不唯一的非聚集索引,如果在这个过程中数据库发生了宕机,这时候会有大量的插入缓冲并没有合并到实际的非聚集索引中。如果是这样,恢复可能需要很长的时间,极端情况下甚至需要几个小时来执行合并恢复操作。
问题:
目前插入缓冲存在一个问题是,在写密集的情况下,插入缓冲会占用过多的缓冲池内存,默认情况下最大可以占用1/2的缓冲池内存。Percona已发布一些patch来修正插入缓冲占用太多缓冲池内存的问题,具体的可以到http://www.percona.com/percona-lab.html查找。简单来说,修改IBUF_POOL_SIZE_PER_MAX_SIZE就可以对插入缓冲的大小进行控制,例如,将IBUF_POOL_SIZE_PER_MAX_SIZE改为3,则最大只能使用1/3的缓冲池内存。
innodb从1.0.x版本开始引入了change buffer,可将其视为insert buffer的升级。从这个版本开始,Innodb存储引擎可以对DML操作——insert、delete、update都进行缓冲,它们分别是:insert buffer、delete buffer、purge buffer。
两次写
如果说show global status like 'innodb_dblwr%'\G
doublewrite一共写了18 445个页,但实际的写入次数为434,(42:1) 基本上符合64:1。
如果发现你的系统在高峰时Innodb_dblwr_pages_written:Innodb_dblwr_writes远小于64:1,那么说明你的系统写入压力并不是很高。
如果操作系统在将页写入磁盘的过程中崩溃了,在恢复过程中,InnoDB存储引擎可以从共享表空间中的doublewrite中找到改页的一个副本,将其拷贝到表空间文件,再应用重做日志。下面显示了由doublewrite进行恢复的一种情况:

090924 11:36:32 mysqld restarted
090924 11:36:33 InnoDB:Database was not shut down normally!
InnoDB:Starting crash recovery.
InnoDB:Reading tablespace information from the.ibd files……
InnoDB:Error:space id in fsp header 0,but in the page header 4294967295
InnoDB:Error:tablespace id 4294967295 in file./test/t.ibd is not sensible
InnoDB:Error:tablespace id 0 in file./test/t2.ibd is not sensible
090924 11:36:33 InnoDB:Operating system error number 40 in a file operation.
InnoDB:Error number 40 means'Too many levels of symbolic links'.
InnoDB:Some operating system error numbers are described at
InnoDB:http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html
InnoDB:File name./now/member
InnoDB:File operation call:'stat'.
InnoDB:Error:os_file_readdir_next_file()returned-1 in
InnoDB:directory./now
InnoDB:Crash recovery may have failed for some.ibd files!
InnoDB:Restoring possible half-written data pages from the doublewrite
InnoDB:buffer……

参数skip_innodb_doublewrite可以禁止使用两次写功能,这时可能会发生前面提及的写失效问题。不过,如果你有多台从服务器(slave server),需要提供较快的性能(如slave上做的是RAID0),也许启用这个参数是一个办法。不过,在需要提供数据高可靠性的主服务器(master server)上,任何时候我们都应确保开启两次写功能。
注意:有些文件系统本身就提供了部分写失效的防范机制,如ZFS文件系统。在这种情况下,我们就不要启用doublewrite了。
自适应哈希索引
哈希(hash)是一种非常快的查找方法,一般情况下查找的时间复杂度为O(1)。常用于连接(join)操作,如SQL Server和Oracle中的哈希连接(hash join)。但是SQL Server和Oracle等常见的数据库并不支持哈希索引(hash index)。MySQL的Heap存储引擎默认的索引类型为哈希,而InnoDB存储引擎提出了另一种实现方法,自适应哈希索引(adaptive hash index)。
InnoDB存储引擎会监控对表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引,所以称之为自适应(adaptive)的。自适应哈希索引通过缓冲池的B+树构造而来,因此建立的速度很快。而且不需要将整个表都建哈希索引,InnoDB存储引擎会自动根据访问的频率和模式来为某些页建立哈希索引。
根据InnoDB的官方文档显示,启用自适应哈希索引后,读取和写入速度可以提高2倍;对于辅助索引的连接操作,性能可以提高5倍。自适应哈希索引是非常好的优化模式,其设计思想是数据库自优化(self-tuning),即无需DBA对数据库进行调整。
查看当前自适应哈希索引的使用状况:show engine innodb status\G
现在可以看到自适应哈希索引的使用信息了,包括自适应哈希索引的大小、使用情况、每秒使用自适应哈希索引搜索的情况。值得注意的是,哈希索引只能用来搜索等值的查询,如select * from table where index_col='xxx',而对于其他查找类型,如范围查找,是不能使用的。因此,这里出现了non-hash searches/s的情况。用hash searches:non-hash searches命令可以大概了解使用哈希索引后的效率。
由于自适应哈希索引是由InnoDB存储引擎控制的,所以这里的信息只供我们参考。不过我们可以通过参数innodb_adaptive_hash_index来禁用或启动此特性,默认为开启。
InnoDB的关键特性-插入缓存,两次写,自适应hash索引的更多相关文章
- InnoDB关键特性之自适应hash索引
一.索引的资源消耗分析 1.索引三大特点 1.小:只在一个到多个列建立索引 2.有序:可以快速定位终点 3.有棵树:可以定位起点,树高一般小于等于3 2.索引的资源消耗点 1.树的高度,顺序访问索引的 ...
- 【InnoDB】插入缓存,两次写,自适应hash索引
InnoDB存储引擎的关键特性包括插入缓冲.两次写(double write).自适应哈希索引(adaptive hash index).这些特性为InnoDB存储引擎带来了更好的性能和更高的可靠性. ...
- Innodb关键特性之自适用Hash索引
一.索引的资源消耗分析 1.索引三大特点 1.小:只在一个到多个列建立索引 2.有序:可以快速定位终点 3.有棵树:可以定位起点,树高一般小于等于3 2.索引的资源消耗点 1.树的高度,顺序访问索引的 ...
- InnoDB Insert Buffer(插入缓冲)
InnoDB Insert Buffer(插入缓冲) 每个存储存储引擎自身都有自己的特性(决定性能以及更高可靠性),而InnoDB的关键特性有: 插入缓冲(Insert Buffer)-->Ch ...
- innodb 关键特性(两次写与自适应哈希索引)
两次写: 场景: 当发生数据库宕机时,可能innodb存储引擎正在写入某个页到表中,而这个页只写了一部分,这种情况被称为部分写失效,如果发生,可以通过重做日志进行恢复,重做日志中记录的是对页的物理操作 ...
- InnoDB关键特性学习笔记
插入缓存 Insert Buffer Insert Buffer是InnoDB存储引擎关键特性中最令人激动与兴奋的一个功能.不过这个名字可能会让人认为插入缓冲是缓冲池中的一个组成部分.其实不然,Inn ...
- InnoDB关键特性之insert buffer
insert buffer 是InnoDB存储引擎所独有的功能.通过insert buffer,InnoDB存储引擎可以大幅度提高数据库中非唯一辅助索引的插入性能. 数据库对于自增主键值的插入是顺序的 ...
- innodb关键特性之double write
# 脏页刷盘的风险 两次写的原理机制 1.解决问题 2.使用场景 3.doublewrite的工作流程 4.崩溃恢复 # doublewrite的副作用 1.监控doublewrite负载 2.关闭d ...
- 影响K8S Pod分配和调度策略的两大关键特性
在Kubernetes中有一个最复杂的调度器可以处理pod的分配策略.基于在pod规范中所提及的资源需求,Kubernetes调度器会自动选择最合适的节点来运行pod. 但在许多实际场景下,我们必须干 ...
随机推荐
- 20181114 Redis
Redis 下载 Windows版本 Windows版本 已经有很久没有更新了,建议还是使用Linux版本 Linux版本 官网下载即可 配置文件 Windows版本 redis.windows.co ...
- 数据结构(六)查找---平衡二叉树(ASL)
前提 我们之前的二叉排序树的插入(构建)是按照我们输入的数据来进行的,若是我们的数据分布不同,那么就会构造不同的二叉树 { , , , , , , , , , } { , , , , , , , , ...
- javascript 学习1
1.javaScript允许对任意数据类型做比较,如boolean与number,false==0//true false === 0//false == 比较:自动转换数据类型进行比较,很多时候得到 ...
- prompt更改MySQL登陆后的提示符
临时生效 mysql> prompt \u@standby \r:\m:\s > PROMPT set to '\u@standby \r:\m:\s >' root@standby ...
- LINQ to SQL 实现 CASE WHEN THEN 语句
Ø 前言 没有什么特别的,只是觉得 LINQ 的功能其实还是蛮强大的,所以简单记录下,算是工作笔记吧,有可能还能帮助到其他同学呢^_^. Ø 下面主要使用了 C# 三元运算符实现实现 SQL 中的 ...
- Hibernate添加日志--log4j
需要导入 slf4j-log4j12-1.6.2.jar slf4j-api-1.6.2.jar log4j-1.2.16.jar 三个jar文件 编写properties文件,建议将日志输出级别设置 ...
- Linux 下安装 storm
一:准备工作 (机器部署情况详见)这篇博客 3台安装supervisor,2台安装nimbus (1)安装jdk1.8 (2)安装zookeeper3.4.5 以上两部分安装可查看这篇博客 (3)下载 ...
- 20155332 2016-2017-2 《Java程序设计》第8周学习总结
20155332 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 创建Logger对象 static Logger getLogger(String name ...
- JavaScript/HTML/CSS 之 iframe自适应高度
最高效简介的手段是利用CSS的内置calc函数: iframe{ height:calc(100vh - 50px) auto;//假令:html顶部有高度为50px的导航条 //min-height ...
- JavaScript之表格操作(二)创建表格病填充表格数据
//创建表格 var tableOptions = { way: "insertBefore", //insertBefore,append positionId: "d ...