innodb的三大特性 1.双写缓冲机制 2.AHI(自适应哈希索引,热点数据直接返回) 3. buffer pool(innodb的缓存)

双写缓冲区(系统表中,2mb)/双写机制(保证数据页的可靠性)

1.innodb在写数据时,先写到缓冲区,在写到实际文件存储位置,如果在写页的过程中发生意外崩溃,InnoDB
在稍后的恢复过程中在 doublewrite buffer 中找到完好的 page 副本用于恢复.

InnoDB 的页大小一般是 16KB,其数据校验也是针对这 16KB 来计算的,将 数据写入到磁盘是以页为单位进行操作的。而操作系统写文件是以 4KB 作为单位 的,那么每写一个 InnoDB 的页到磁盘上,操作系统需要写 4 个块。在极端情况下(比如断电)往往并不能保证这一 操作的原子性,16K 的数据,写入 4K 时,发生了系统断电或系统崩溃,只有一 部分写是成功的,这种情况下会产生 partial page write(部分页写入)问题。这 时页数据出现不一样的情形,从而形成一个”断裂”的页,使数据产生混乱。在 InnoDB 存储引擎未使用 doublewrite 技术前,曾经出现过因为部分写失效而导致 数据丢失的情况。

buffer pool

innodb缓存磁盘中的页向操作系统申请了一片连续的内存,叫做buffer pool

image.png
每个控制块大约占用缓存页大小的 5%,而我们设置的 innodbbuffer_pool_size 并不包含这部分控制块占用的内存空间大小,也就是说
InnoDB 在为 Buffer Pool 向操作系统申请连续的内存空间时,这片连续的内存空 间一般会比 innodb_buffer_pool_size 的值大 5%左右。
**
缓存页的哈希处理_**
当我们需要访问一个页时,根据表空间号 + 页号来定位一个页的,也就相当于表空间号 + 页号是一个 key,缓存页就是对应的 value
所以我们可以用表空间号 + 页号作为 key,缓存页作为 value 创建一个哈希 表,在需要访问某个页的数据时,先从哈希表中根据表空间号 + 页号看看有没
有对应的缓存页,如果有,直接使用该缓存页就好,如果没有,那就从 free 链表中选一个空闲的缓存页,然后把磁盘中对应的页加载到该缓存页的位置。

三个链表

1.free链表,记录空闲的缓存页
image.png

2.flush链表,存储脏页的链表凡是修改过的缓存页对应的控制块 都会作为一个节点加入到一个链表中,因为这个链表节点对应的缓存页都是需要
被刷新到磁盘上的

3.lru链表,记录最近未使用的缓存页,当缓存页不够时淘汰部分最近最少使用的页

多个 Buffer Pool 实例

在多线程环境下,访问 Buffer Pool 中的各种链表都需要加锁处理,在Buffer Pool 特别大而且多线程并发访问特别高的情况下,单一的 Buffer Pool 可能会影响请求的处理速度。所以在 Buffer Pool 特别大的时候,我们可以把它们拆分成若干个小的 Buffer Pool,每个 Buffer Pool 都称为一个实例,它们都是独立的,独立的去申请内存空间,独立的管理各种链表,所以在多线程并发访问时并不会
相互影响,从而提高并发处理能力。

image.png

其中的 Insert/Change Buffer 主要是用于对二级索引的写入优化,Undo 空间
则是 undo 日志一般放在系统表空间,但是通过参数配置后,也可以用独立表空
间存放,所以用虚线表示。