索引
聚集索引
- 唯一
- 和物理地址相关
MySQL中的聚集索引默认为主键Primary key。
其中最主要的特性就是和物理地址相关了。
| physical | logic_index |
|---|---|
| 0x00 | 1 |
| … | … |
| 0xff | 255 |
当我们查找一条记录,知道逻辑上的id之后,就能够知道准确的物理磁盘地址,查找特别快速。
非聚集索引
非聚集内存的话,可以重复页可以不重复,更主要的是,他的物理地址和逻辑地址是无关的。
所以每次通过非聚集索引进行数据查找的话是随机的,并不能快速的去锁定一条数据的物理地址。
插入缓冲
insert buffer
非聚集索引的情况下,准确的锁定一条数据消耗不小。
尤其是存在多条操作,如果每条都直接操作磁盘,消耗更大。
对此,增加了insert buffer
- 全部数据都在缓冲中,速度就会很快
- 单页数据修改多条可合并为一条
当满足如下条件就会启用
- 非聚集索引
- 如果是聚集索引还用这么麻烦么
- 索引非唯一键
- 如果还需要查索引确保唯一,就失去了意义
极端情况下,大量
insert buffer宕机写到日志,重启数据恢复时,大量索引信息在日志中,恢复缓慢。
也就是说操作缩减为原来的1/3,减少了2/3的请求。
change buffer
change buffer是insert buffer的升级版本,提供了更多语句的buffer。
insert bufferdelete bufferpurge buffer
通过innodb_change_buffering进行功能设置
insertsdeletespurgesallnone
支持设置为以上四种。
该buffer会占用缓冲池的容量,最大可占用到一半,可以通过innodb_change_buffer_max_size进行设置。
可设置最大值为50,表示,也就是innodb_buffer_pool_size的一半,默认为25.
插入逻辑
存放地址
insert buffer存放在ibdata1共享表空间中,全局为一棵树。
对于文件恢复,不能只使用
ibd独享空间,还需要配合共享空间回复非聚集索引。
非叶节点
| name | size(byte) | description |
|---|---|---|
| space | 4 | 表空间id |
| marker | 1 | 兼容 |
| offset | 4 | 页偏移量 |
准备插入到Insert Buffer的数据,首先构造上述的search key,然后进行树的搜索。
如果辅助索引在缓冲池中,会直接插入,如果不在,就会闲插入到
Insert Buffer中。
叶子结点
| name | size(byte) | description |
|---|---|---|
| space | 4 | - |
| marker | 1 | - |
| offset | 4 | - |
| metadate | 4 | 元信息 |
| record | - | 原插入信息 |
所以Insert Buffer每条数据,都会有额外的13字节空间占用。
其中metadata结构如下
| name | size | description |
|---|---|---|
| IBUF_REC_OFFSET_COUNT | 2 | 进入顺序 |
| IBUF_REC_OFFSET_TYPE | 1 | - |
| IBUF_REC_OFFSET_FLAGS | 1 | - |
写入Insert Buffer的数据,最后都会写回辅助索引,因此,要确保辅助索引的容量足够。
Insert Buffer Bitmap
| name | size | description。 |
|---|---|---|
| IBUF_BITMAP_FREE | 2 | 0:无可用空间 1:大于 1/32页2:大于 1/16页3:大于 1/8页 |
| IBUF_BITMAP_BUFFERED | 1 | 1:该辅助页索引有记录被缓存在树中 |
| IBUF_BITMAP_IBUF | 1 | 1: 该页为树索引页 |
Merge Insert Buffer
Insert Buffer只是内存中的数据,具体写入还得受限于物理磁盘,也就是辅助索引的存储。
和脏页同步一样,Insert Buffer最终得merge到辅助索引页中去。
- 辅助索引页被加载到缓冲池
- 每次读取麻烦,但是刚好读取了,趁机插入
- 辅助索引页无可用空间
-
Insert Buffer Bitmap检测空间少于1/32,为了保证后续数据能写入,强制合并更新
-
-
Master Thread-
Master Thread周期操作,进行合并
-