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. 但在许多实际场景下,我们必须干 ...
随机推荐
- C语言实现KMP模式匹配算法
next: /*! * Description: * author scictor <scictor@gmail.com> * date 2018/7/4 */ #include < ...
- bin内置函数
光棍们对1总是那么敏感,因此每年的11.11被戏称为光棍节.小Py光棍几十载,光棍自有光棍的快乐.让我们勇敢地面对光棍的身份吧,现在就证明自己:给你一个整数a,数出a在二进制表示下1的个数,并输出. ...
- 红外条码扫描器的另类使用C#版
3年前写了一篇<USB口的红外条形码扫描器的另类使用>,不过相关代码是VB编写,在这几年之间,有许多网友提出需要C#版的,起初还以为由VB修改C#应该很容易,最近研究了一下,发现C#和VB ...
- 类的初始化过程(难点)--------java基础总结
前言:看到这么好的东西,忍不住又写到了博客上面 Student s = new Student();在内存中究竟做了哪些事情呢? ①加载student.class文件进内存. ②为栈内存s开辟空间. ...
- P4891 序列
P4891 序列 题目描述 给定两个长度为 n 的序列 A 和 B,定义序列 \(C_i=\max\limits_{j=1}^i A_j\) 定义当前的价值是 $\prod\limits_{i=1}^ ...
- Spark进阶之路-Spark提交Jar包执行
Spark进阶之路-Spark提交Jar包执行 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在实际开发中,使用spark-submit提交jar包是很常见的方式,因为用spark ...
- TCP的代码
视频已经发布,这里是所有的代码仅供参考. TCP服务器: MainWindow里面的代码: using System; using System.Collections.Generic; using ...
- Python复习笔记(一)高级变量类型
目标 列表元组 字典 字符串 公共方法 变量高级 01. 列表 02. 元组 03. 字典 04. 字符串 1)判断类型 - 9 2) 查找和替换 - 7 3) 大小写转换 - 5 4) 文本对齐 - ...
- python 爆破
python 爆破 #!/usr/bin/python #-*- coding: GB2312 -*- #author:loversorry import urllib2 import urllib ...
- 关于Mac OS虚拟机下共享文件夹的方法
1.确保左上角苹果标志的旁边是“Finder”: 2.点击"Finder": 3.选择“偏好设置设置”: 4.然后在“通用”标签下勾选“已连接服务器”: OK,搞定! 完成以上 ...