show engine innodb status

一块连续的内存空间,用来缓冲从文件中读取的数据信息。
bufferPool的页大小与表空间的页大小保持一致,均为16KB.
buffperPool的前面是控制块,存放着缓冲页的一些基本信息,如所属表空间编号、页号、缓冲页在pool中的地址、链表节点信息等。

free链表

所有空闲的缓冲页会组成也给双向链表,头节点是单独申请内存的一个头节点。当查询数据要放入缓冲页时,从空闲链表中取出一个空闲页,并将其从空闲链表移除即可。
mysql通过表空间号+页号作为缓冲页的hash key,缓冲页控制块地址为hash value,根据此hash判断数据是否已经在缓冲池中。

flush链表

脏页链表,当页数据被修改后,该页加入到flush链表中,mysql会进行批量刷数据到磁盘。

LRU机制

前5/8为young区,后3/8为old区
对于预读或者全表扫描的情况,数据初次访问会被放在old区的头处,后续再次访问时才会将页移到young区头部。
对于全被扫描会多次读取页的情况,当old区的页被访问时间间隔小于1秒时,不会移动页到young区。
对于young区的页面后1/4的页被访问时移动到头部,其余的被访问不移动。

脏页刷新

  • 从lru尾部刷新脏页
  • 从flush链表刷新脏页

    bufferPool多实例

    单个bufferpool的各种链表在访问时会加锁,当并发高时会影响性能,因此可以拆分为多个bufferPool实例。
    当设置多个实例时,每个pool的大小最小为1G

    bufferPool大小调整

    5.7.5之后可以运行时调整大小,且将bufferPool改为右一个个的chunk组成,每个chunk为一片连续的内存空间,里面包含若干个控制块和缓冲页,innodb每次以chunk为单位向os申请内存。
    使用chunck的概念是为了避免以前调整pool大小时,需要重新申请连续空间并对旧空间内容复制,复制行为很耗时。