InnoDB内存相关的数据结构主要包含以下几种:
Buffer Pool 是在主存的一片区域,主要用来缓存表和索引数据供InnoDB访问。Buffer Pool允许频繁访问的数据可以加速直接从内存读取。专业的服务器,一般使用80%的物理内存作为Buffer Pool。
为了提高大量读取操作的性能,Buffer Pool被分割为多个pages。为了高效管理缓存,buffer pool的实现是作为一个linked list。很少使用的数据采用LRU算法淘汰。
BufferPool 采用LRU算法淘汰。当需要新增一个page到BufferPool时,最近最少使用的page将会被驱逐,一个新page会被加入中间。中间插入的策略会把list切分为两个list:
这个算法切分list为两个sublist。old sublit 存储最少使用的页,这些爷会被优先移除。算法的主要操作包含:
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]
change buffer 是一个特殊的缓存,主要缓存二级索引页,而这些索引页不在buffer pool.Change Buffer的更新会基于 INSERT, UPDATE, or DELETE operations (DML) 操作结果,这些将会通过其他的读取操作合并到buffer pool.
与聚集索引不同,二级索引不唯一的,插入二级索引也是非顺序的。同样的,删除和更新操作可能影响的二级索引不在同一个索引树。合并缓存发生在,受影响的行再其他操作读取进入buffer pool时,避免大量的随机IO操作读取二级索引到buffer pool.
合并Change buffer有可能花费几个小时,当大量的行数和二级索引更新时。在这段时间,会产生大量的IO操作。 Change buffer merging 也可能发生于一个事务提交,或者一个停机重启操作。
在内存中, change buffer 属于buffer pool的一部分。在磁盘上,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
自适应哈希索引特性使InnoDB能够在具有适当的工作负载和足够的缓冲池内存的系统上执行更像内存中的数据库,而不牺牲事务特性或可靠性。自适应hash索引可以通过开启 innodb_adaptive_hash_index变量开启,或者通过–skip-innodb-adaptive-hash-index关闭。
根据搜索模式,哈希索引根据使用索引键的前缀构建。前缀可以是任意长度,并且可能只有B树中的某些值出现在哈希索引中。哈希索引是根据需要为经常访问的索引页构建的。
Log buffer是内存中的一块区域,主要保存写入硬盘的日志数据。Log Buffer的内存大小通过参数innodb_log_buffer_size指定。默认大小为16MB.
innodb_flush_log_at_trx_commit变量控制什么时候log buffer会被写入磁盘。innodb_flush_log_at_timeout 变量控制log刷新的频率。