[TOC]
![](https://box.kancloud.cn/52caa8f44ca2050808d892aa23717226_782x342.png)
## 插入缓存
### 1.Insert Buffer
innodb使用insert buffer"欺骗"数据库:对于为非唯一索引,辅助索引的修改操作并非实时更新索引的叶子页,而是把若干对同一页面的更新缓存起来做合并为一次性更新操作,转化随机IO 为顺序IO,这样可以避免随机IO带来性能损耗,提高数据库的写性能。
![](https://box.kancloud.cn/af9690a77ee993abeaedceb861a5a894_815x140.png)
![](https://box.kancloud.cn/d68efa9ed3220fc7016e36450b2a534e_826x388.png)
IBUF_POOL_SIZE_PER_MAX_SIZE参数修改默认为2 即为最大缓存为1/2 如果将其改为3 这最大能够使用1/3的缓存池内存。
### 2.Change Buffer
innodb 1.0.x才开始引用 是Insert Buffer的升级版,
InnoDB存储引擎可以对DML操作————INSERT、DEKETE、UPDATE进行缓冲,他们分别是:Insert Buffer、Delete Buffer、Purge buffer。
Change Buffer对象也是非唯一的辅助索引。
对一条记录进行UPDATE操作可能分为两个过程:
(1)Delete Buffer对应 UPDATE操作将记录标记为已删除;
(2)Purge Buffer对应UPDATE操作真正将记录删除。
innodb 2.0.x 开始通过参数 innodb_change_buffer_max_size来控制 查询:`show variables like 'innodb_change_buffer_max_size'\G`
默认为25 即为1/4的缓冲池内存空间。最大为50值即为1/2的缓冲池内存空间。
### Insert Buffer内部实现
Insert Buffer 是一棵B+树,因此其也由叶节点和非叶节点组成。非叶节点存放的是查询的 search key(键值)
如图:
![](https://box.kancloud.cn/eed836d60bbbd23b121d5687cc77e141_506x116.png)
![](https://box.kancloud.cn/38925d2d34ab67320d48067aef2398eb_835x189.png)
### Merge Insert Buffer
(1)辅助索引页被读取到缓冲池时,
(2)Insert Buffer Bitmap 页追踪到该辅助索引页已无可用空间时;
(3)Master Thread。
![](https://box.kancloud.cn/9df72b3b1ff6339c0d692b1a23fea0f8_842x435.png)
![](https://box.kancloud.cn/adf7fde3b579dbace81454ed532dea58_829x339.png)
*****
## 两次写
doublewrite由两部分组成,一部分是内存的doublewrite buffer,大小为2MB,另一部分是物理磁盘上共享表空间中联系的128个页,即2个区(extent),大小同样为2MB。
脏读刷新先复制到内存中的doublewrite buffer,之后doublewrite buffer再分两次,每次1MB写入共享表空间的物理磁盘,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题。如图:
![](https://box.kancloud.cn/ff91b539d5e90a5e622dc91c5c78892f_787x403.png)
通过命令`SHOW GLOBAL STATUS LIKE 'innodb dblwr%'\G`观察doublewrite运行的情况。
*****
## 自适应哈希索引
InnoDB存储引擎会监控各索引页的查询。如果观察到简历哈希所以可以带来的速度提升,则建立哈希索引,称为自适应哈希索引(Adaptive Hash Index,AHI)。AHI是通过缓冲池的B+树页构造而来,因此建立的速度很快,而且不需要对整张表构建哈希索引。InnoDB存储引擎会自动根据访问的频率和墨水来自动地为某些热点页建立哈希索引。
AHI有个要求,连续访问模式必须一样的例如:
![](https://box.kancloud.cn/7e402b7beeac0b568815f52c3424e2c9_890x210.png)
启用之后读取写入可以提高2倍。辅助索引可以提高5倍。
通过`SHOW ENGINE INNODB STATUS\G;`查看状态:
![](https://box.kancloud.cn/e6f6f530de4ff7bc1f199a83dabe9c38_822x392.png)
通过结果可以考虑是禁用还是启动此特性,默认AHI启用;
*****
## 异步IO
为了提高磁盘操作性能,当前的数据库系统都采用异步IO(Asynchronous IO,AIO)的方式来处理磁盘操作。
与AIO对应的是 Sync IO,Sync IO每次进行IO操作 需要等到改操作结束才能继续接下来的操作。但是如果用户是一条索引扫描的查询,那么需要扫描索引页,也就是需要进行多次的IO操作。如果是这样的话就没有必要了。
用户发送一个IO请求就可以发送另一个IO请求,当全部发送完毕,等待所有的IO操作的完成,这就是AIO。
AIO的另一个优势 可以进行IO Merge操作,也就是将多个IO何必为一个IO。
若通过Linux操作系统下的iostat 命令 可以观察 rrqm/s和wrqm/s。
InnoDB 1.1.x 开始(InnoDB Plugin 不支持)提供了内核级别AIO的支持,称为 NatIve AIO。因此编译或者运行该版本MySQL时需要libaio的支持。若没有则会出现如下的提示:
![ ](https://box.kancloud.cn/caa0fef240a025c16fbe4d9d842f0009_846x84.png)
Native AIO只有windows 和linux系统支持。Mac OSX不支持。
参数innodb_use_native_aio 控制师傅启动 liunx默认不启动。
`SHOW VARIABLES LIKE 'innodb_use_native_aio'\G`
![](https://box.kancloud.cn/18a374770ed2be0874341ccf079c9cf2_677x117.png)
官方显示,启用NatIve AIO,恢复速度可以提高75%。
read ahead方式读取都是通过AIO完成,脏页的刷新和磁盘写入操作则全部由AIO完成。
*****
## 刷新邻接页
InnoDB存储引擎还提供了Flush Neighbor Page(刷新邻接页)的特性。工作原理:当刷新脏页时,InnoDB存储引擎会检测所在区的所有页,如果是脏页,那么一起进行刷新。
参数innodb_flush_neighbors 控制是否启用改特性.如果是机械硬盘建议启用,如果是固态硬盘就不建议使用 IOPS性能的磁盘 则建议设置为0,关闭此特性。
*****
## 启动、关闭和恢复
关闭时参数innodb_fast_shutdown影响着表存储引擎InnoDB的行为。该参数可取值为0、1、2,默认为1
![](https://box.kancloud.cn/fc3c79f738da0285b045df30098e7257_824x319.png)
当正常关闭MySQL数据库时,下次的启动应该会非常“正常”。但是没有正常关闭 如用kill命令关闭数据库,在MySQL 数据库运行中重启服务器,或者关闭数据库时,将参数innodb_fast_shuidown设为了2时,下次MySQL数据库启动时都会对InnoDB存储引擎的表进行恢复操作。
参数innodb_force_recovery影响了正规InnoDB存储引擎恢复的状况。默认为0,代表当发生需要恢复时,进行所有恢复的操作,当不能进行有效恢复时,如数据页发送了corruption,MySQL数据库可能发送宕机(crash),并把错误写入错误日志中去。
如果用户知道怎么进行恢复 比如进行alter table操作是发生意外了,数据库重启会对InnoDB进行回滚操作,对于大表涞水需要很长时间,所以可以把表删除,从备份中导入数据到表。速度就会比回滚操作快。
![](https://box.kancloud.cn/9b3c7309d263250656fdfb9387f8fbf9_804x237.png)
![](https://box.kancloud.cn/d44c59d69b064867a47fd4698341e298_824x227.png)
如果innodb_force_recovery 设置为3 则不需要回滚,因此数据库很快就启动完成了。 但是需要仔细确认是否需要回滚事务操作。