InnoDB内存数据结构

InnoDB内存相关的数据结构主要包含以下几种:

  • Buffer Pool
  • Change Buffer
  • Adaptive Hash Index
  • Log Buffer

Buffer Pool

Buffer Pool 是在主存的一片区域,主要用来缓存表和索引数据供InnoDB访问。Buffer Pool允许频繁访问的数据可以加速直接从内存读取。专业的服务器,一般使用80%的物理内存作为Buffer Pool。
为了提高大量读取操作的性能,Buffer Pool被分割为多个pages。为了高效管理缓存,buffer pool的实现是作为一个linked list。很少使用的数据采用LRU算法淘汰。

Buffer Pool LRU 算法

BufferPool 采用LRU算法淘汰。当需要新增一个page到BufferPool时,最近最少使用的page将会被驱逐,一个新page会被加入中间。中间插入的策略会把list切分为两个list:

  • 在头部,新页会被最新访问
  • 在尾部,老的page不会被频繁访问
    InnoDB内存数据结构_第1张图片

这个算法切分list为两个sublist。old sublit 存储最少使用的页,这些爷会被优先移除。算法的主要操作包含:

  • 3/8 的buffer pool容量用作old sublist
  • 插入元素的中间节点为新元素list的末尾和老元素list的头部
  • 当InnoDB读取一个page到Buffer Pool,首先会插入数据到中间(老数据的头部)。
  • 访问老数据的一个page,会使这部分数据移动到新数据的头部。

Buffer Pool Configuration

  • buffer pool size 配置文档参考: https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool-resize.html
  • 设置多个buffer pool instance 参考文档:https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-buffer-pools.html

监控 Buffer Pool

SHOW ENGINE INNODB STATUS 语句可以查看Buffer Pool的使用情况

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 137363456; in additional pool allocated 0
Dictionary memory allocated 223332
Buffer pool size   8192
Free buffers       1
Database pages     8190
Old database pages 3003
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 749906, not young 152695637
0.00 youngs/s, 0.00 non-youngs/s
Pages read 3988618, created 530179, written 4842443
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 8190, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
  • youngs/s 指标只应用于old pages。主要基于访问page的数而不是page总数。如果发现很低的youngs/s,需要降低淘汰时间或者减少 buffer pool中的old sublist大小。
  • non-youngs/s也只用于old pages。主要基于访问page的数而不是page总数。
  • young-making 适用于所有的buffer pool

Change Buffer

change buffer 是一个特殊的缓存,主要缓存二级索引页,而这些索引页不在buffer pool.Change Buffer的更新会基于 INSERT, UPDATE, or DELETE operations (DML) 操作结果,这些将会通过其他的读取操作合并到buffer pool.

InnoDB内存数据结构_第2张图片
与聚集索引不同,二级索引不唯一的,插入二级索引也是非顺序的。同样的,删除和更新操作可能影响的二级索引不在同一个索引树。合并缓存发生在,受影响的行再其他操作读取进入buffer pool时,避免大量的随机IO操作读取二级索引到buffer pool.
合并Change buffer有可能花费几个小时,当大量的行数和二级索引更新时。在这段时间,会产生大量的IO操作。 Change buffer merging 也可能发生于一个事务提交,或者一个停机重启操作。
在内存中, change buffer 属于buffer pool的一部分。在磁盘上,change buffer属于系统表空间。

监控 Change Buffer

-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 4425293, used cells 32, node heap has 1 buffer(s)
13577.57 hash searches/s, 202.47 non-hash searches/s

Adaptive Hash Index 自适应哈希索引

自适应哈希索引特性使InnoDB能够在具有适当的工作负载和足够的缓冲池内存的系统上执行更像内存中的数据库,而不牺牲事务特性或可靠性。自适应hash索引可以通过开启 innodb_adaptive_hash_index变量开启,或者通过–skip-innodb-adaptive-hash-index关闭。
根据搜索模式,哈希索引根据使用索引键的前缀构建。前缀可以是任意长度,并且可能只有B树中的某些值出现在哈希索引中。哈希索引是根据需要为经常访问的索引页构建的。

Log Buffer

Log buffer是内存中的一块区域,主要保存写入硬盘的日志数据。Log Buffer的内存大小通过参数innodb_log_buffer_size指定。默认大小为16MB.
innodb_flush_log_at_trx_commit变量控制什么时候log buffer会被写入磁盘。innodb_flush_log_at_timeout 变量控制log刷新的频率。

你可能感兴趣的:(MySql)