InnoDB体系结构学习笔记

后台线程 Master Thread

核心的后台线程,主要负责将缓冲池的数据异步刷新到磁盘,保证数据的一致性,包括(脏页的刷新)、合并插入缓冲、(UNDO页的回收)等

IO Thread

4个write、4个read、1个insert buffer、1个log

参数innodb_read_io_threads和innodb_write_io_threads可以进行设置。

Purge Thread

回收已经使用并分配的UNDO页。(从Innodb 1.1版本开始独立线程)

从Innodb 1.2版本开始,Innodb支持多个Purge Thread,进一步加快UNDO页的回收。同时由于Purge Thread需要离散的读取UNDO页,这样能更进一步利用磁盘的随机读取性能。

Page Cleaner Thread

在Innodb 1.2版本中引入,将之前版本中脏页的刷新操作都放入到单独的线程中完成。减轻Master Thread的工作以及用户查询线程的堵塞,进一步提高InnoDB存储引擎的性能。

内存 缓冲池

缓冲池的配置通过参数innodb_buffer_pool_size来设置。

show variables like 'innodb_buffer_pool_size';

缓冲池中缓存的数据页类型有:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引、Innodb存储的锁信息(lock info)、数据字典信息(data dictionary)等。

InnoDB 1.0.x版本开始,允许有多个缓冲池示例。每个页根据哈希值平均分配到不同的缓冲池中。好处是减少数据库内部的资源竞争,增加数据库的并发处理能力。通过参数innodb_buffer_pool_instances来进行配置,默认为1。

show variables like 'innodb_buffer_pool_instances'; LRU List、Free List和Flush List

数据库中的缓冲池通常是通过LRU(Latest Recent Used,最近最少使用)算法进行管理的。即最频繁进行的页在LRU列表的前端,而最少使用的页在LRU列表的尾端。当缓冲池不能存放新读到的页时,将首先释放LRU列表中的尾端的页。

InnoDB的缓冲池对传统的LRU算法做了一些优化。在LRU列表中还加入了midpoint位置。新读取到的页,虽然是最新访问的页,但并不是直接放入到LRU列表的首部,而是放入LRU列表的midpoint位置。这个算法在InnoDB存储引擎下称为midpoint insertion strategy。默认情况下位置在LRU列表长度的5/8处。通过参数innodb_old_blocks_pct控制。

为什么不使用传统的LRU算法,如果直接将读取到的页放入到LRU的首部,那么某些SQL操作可能会是缓冲池中的页全部被刷出,从而影响缓冲池的效率。常见的这类操作为索引或数据的扫描操作。这类操作需要访问表中的许多页,甚至是全部的页,而这些页仅仅是这次操作需要的,并不是热点数据。

同时,InnoDB使用参数innodb_old_blocks_time管理页读取到midpoint位置后等待多久才会被加入到LRU的热端(midpoint之前的称为new列表热端,之后的列表称为old列表)。可以通过下面的设置尽可能使LRU列表中热点数据不被刷出。

set global innodb_old_blocks_time = 1000;

如果预估自己的热点数据不止63%,那么通过下面的设置来减少热点页的刷出,但是还是会被刷出。

set global innodb_old_blocks_time = 20;

当数据库刚启动时,LRU列表是空的,即没有任何的页。这是页都存放在Free列表中,当需要从缓冲池中分页时,首先从Free列表中查找是否可用的空闲页,若有则从Free列表中删除,放入到LRU列表中。否则,根据LRU算法,淘汰LRU列表末尾的页,分配给新的页。

当页从LRU列表的old部分加入到new部分时,称此时发生的操作为page made young,而因为innodb_old_blocks_time的设置而导致没有从old部分变为new部分的操作称为page not made young。

通过命令查看LRU列表及Free列表的使用状况。

show engine innodb status\G; BUFFER POOL AND MEMORY ---------------------- Total large memory allocated 137428992 Dictionary memory allocated 417853 Buffer pool size 8191 Free buffers 7724 Database pages 467 Old database pages 0 Modified db pages 0 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 0, not young 0 0.00 youngs/s, 0.00 non-youngs/s Pages read 433, created 34, written 36 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: 467, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0]

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/932cc4095322a45ecdd8721cfed585de.html