innodb体系架构

Innodb体系架构

Innodb存储引擎有多个内存块,可以认为这些内存块组成了一个大的内存池,负责如下工作:
① 维护所有进程、线程需要访问的多个内部数据结构;
② 缓存磁盘上的数据,方便快速的读取;同时在对磁盘文件的数据修改之前在这里缓存;
③ 重做日志(redo log)缓冲。

后台线程的作用是:
负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据;将已修改的数据文件刷新到磁盘文件;保证在数据库发送异常的情况下innodb能恢复到正常运行状态。

一、后台线程

1.1、Master Thread

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

1.2、IO Thread

Io thread:write、read、insert buffer、log io thread
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] ,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
523598 OS file reads, 147171381 OS file writes, 15342668 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 39.79 writes/s, 5.20 fsyncs/s

可以看到:
IO Thread 0 为insert buffer thread;
IO Thread 1 为 log buffer thread;
读写线程是根据参数innodb_read_io_threads及innodb_write_io_threads来设置,且读线程的ID总是小于写线程。

1.3、Purge Thread

事务被提交后,其所使用的undolog可能不再需要,因此需要purgethread来回收已经使用并分配的undo页。

1.4、Page Cleaner Thread

是在innodb 1.2.x版本中引入的。其作用是将之前版本中脏页的刷新操作都放入到单独的线程中来完成,减轻master thread的工作以及对于用户查询线程的阻塞,进一步提高innodb存储引擎的性能。

二、内存

INNODB内存由三部分组成:缓冲池(buffer pool),重做日志缓冲池(redo log buffer)和额外的内存池(additional memory pool)

2.1 缓冲池(buffer pool)

MySQL> show variables like 'innodb_buffer_pool_size';

Innodb存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可将其视为基于磁盘的数据库系统。由于CPU速度与磁盘速度之间的鸿沟,基于磁盘的数据库系统通常是由缓存池技术来提高数据库的整体性能。

缓冲池简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库造成的性能影响。在数据库中进行页的读取操作,首先将从磁盘读取的数据库放在缓冲池中,下一次再次读取相同的页时,首先会判断该页是否在缓冲池,如果在则该页被命中,直接读取。否则,读取磁盘上的页。
对于数据库中页的修改操作,则首先修改在缓冲池中的数据页,然后再以一定的频率刷新到磁盘上。
缓冲池的配置可以通过参数innodb_buffer_pool_size来设置。
缓冲池中缓存的数据页类型有:索引页、数据页、undo页、插入缓冲、自适应哈希索引、innodb存储的锁信息、数据字典等。

2.2 重做日志缓冲池(redo log buffer)

MySQL> show variables like 'innodb_log_buffer_size';

Innodb存储引擎的内存区域除了有缓冲池,还有redo log buffer。Innodb存储引擎首先将重做日志信息放入到缓冲区,然后按照一定的频率刷新到重做日志文件。
innodb_flush_log_at_trx_commit=0/1/2

2.3额外的内存池(additional memory pool)

mysql> show variables like 'innodb_additional_mem_pool_size';

InnoDB用来保存数据字典喝其他内部数据结构的内存池的大小。数据库中的表数量越多,参数值应该越大。

2.4 LRU List、Free List、Flush List

InnoDB存储引擎如何对缓冲池这块区域进行管理呢?缓冲池中页的大小默认为16KB,同时使用LRU算法(latest recent used最近最少使用)对缓冲池区域进行管理。即最频繁使用的数据页放在LRU列表前端,最少使用的数据页放在LRU列表的尾端。InnoDB存储引擎对传统的LRU算法进行了一些优化,在LRU列表中加入了midpoint位置。新读取到的数据页,虽然是最新访问的,但不是直接放入到LRU列表的首部,而是放入到LRU列表的midpoint位置,默认配置下,midpoint为LRU列表长度的5/8处(有参数innodb_old_blocks_pct控制),也就是新读取到的页放入到LRU列表尾端的37%的位置。
之所以不直接将读取到的数据页放到LRU列表的首部,是因为某些SQL操作可能会访问表中的很多数据页,而这些数据页只是本次查询所需要,直接放到LRU列表的首部,会将所需要的热点数据从LRU列表中移除,导致下次查询需要访问硬盘。
InnoDB还引入了另一个参数来进一步管理LRU列表,该参数是innodb_old_blocks_time,表示数据页读取到midpoint位置后,需要多久才能将该数据页加入到LRU列表的热端。

原文地址:https://www.cnblogs.com/icyblog/p/7235932.html