MySQL Innodb体系架构

学习笔记

Innodb体系架构

MySQL Innodb体系架构_第1张图片

  1. Innodb有多个内存块,组成内存池。
  2. 多个后台线程
    2.1. Master Tread:核心线程,主要负责同步缓冲池与磁盘的数据
    2.2. IO线程:负责IO请求的回调处理
    2.3. Purge 线程: 回收已经使用并分配的undo页
    2.4. Page Cleaner 线程:刷新之前版本的脏页操作

内存

内存结构:
MySQL Innodb体系架构_第2张图片
数据页、索引页、undo页、插入缓冲、自适应hash索引、Innodb存储锁信息、数据字典信息等。

缓冲池

Innodb是基于磁盘存储的,并将记录按照页的方式进行管理。
缓冲池就是一块内存区域,通过内存的速度来弥补直接操作磁盘速度较慢对数据库的影响。
对于数据库页的修改操作,首先会修改缓冲池中的页,然后以一定频率刷新到磁盘上,注意的是,并不是每次修改页都会触发刷新到磁盘上,而是通过一种checkpoint的机制刷新磁盘。

对于Innodb而言,其缓冲池的配置参数通过Innodb_buffer_pool_size设置。

mysql> show variables like '%innodb_buffer_pool_size%'\G;
*************************** 1. row ***************************
Variable_name: innodb_buffer_pool_size
Value: 134217728
1 row in set, 1 warning (0.01 sec)

ERROR:
No query specified

从Innodb 1.0.x 版本开始,允许有多个缓冲池实例。每个页根据hash平均分配到不同的缓冲池实例中,这样可以减少数据库内部资源竞争,增加数据库并发处理能力。可以通过参数innodb_buffer_pool_instances设置。

mysql> show variables like '%innodb_buffer_pool_instances%'\G;
*************************** 1. row ***************************
Variable_name: innodb_buffer_pool_instances
        Value: 1
1 row in set, 1 warning (0.00 sec)

ERROR:
No query specified

数据库的缓冲池是通过LRU(Latest Recent used,最近最少使用)算法进行管理的。最频繁使用的页在LRU前端,最少使用的在LRU最后。当缓冲池不能存放新读取的页时,首先释放最尾端的。
缓冲池页的默认大小为16KB,Innodb中LRU加入了midpoint位置,新读取的页,会放到midpoint位置。默认在LRU列表的5/8处,midpoint之前的页称为new 列表,之后的页称为old 列表。midpoint位置可由参数Innodb_old_blocks_pct控制。

mysql> show variables like 'innodb_old_blocks_pct'\G;
*************************** 1. row ***************************
Variable_name: innodb_old_blocks_pct
        Value: 37
1 row in set, 1 warning (0.00 sec)

ERROR:
No query specified

采用midpoint而不是直接将读取的页放在LRU的首部的原因是,避免将不活跃的数据刷出缓冲池,比如:一次全表查询,仅仅是这次查询使用而已,并不是真正活跃的页,如果放到首部可能会将真正活跃的页刷新出去。

为了解决这个问题,Innodb加入了新的参数innodb_old_blocks_time 来进一步管理LRU列表。当读取到mid位置时,需要过多长时间才能插入到LRU热端。这样可以尽可能的保证热点数据不被刷出。

mysql> show variables like 'innodb_old_blocks_time'\G;
*************************** 1. row ***************************
Variable_name: innodb_old_blocks_time
        Value: 1000
1 row in set, 1 warning (0.00 sec)

ERROR:
No query specified

当数据库刚启动时,LRU列表是空的,这时页都存放在free列表中。当需要从缓冲池中分页时,首先需要判断free列表中是否有可用的空闲页,如果有就从free列表中删除,放入LRU列表中。否则根据计算,将LRU中末尾的页删除,将该内存空间分配给新的页。当LRU列表中的页从old 到 young 的过程叫做,page made young。由于innodb_old_blocks_time 参数,导致页没有从old 到 young的过程叫做page not made young。
Innodb 1.2版本开始,可以通过INNODB_BUFFER_POOL_STATS 表来查询缓存池状态

SELECT
	POOL_ID,
	POOL_SIZE,
	FREE_BUFFERS,
	DATABASE_PAGES,
	HIT_RATE,
	PAGES_MADE_YOUNG,
	PAGES_NOT_MADE_YOUNG 
FROM
	information_schema.INNODB_BUFFER_POOL_STATS;

MySQL Innodb体系架构_第3张图片

POOL_SIZE :共有多少个页/32768 * 8 页 , 32768*16K * 8 = 4G 缓存池大小
DATABASE_PAGES:LRU列表页数量
HIT_RATE:缓存池命中率,hit_rate/1000.如果不应该小于95%

Innodb存储引擎1.0.x 之后开始支持压缩页的功能,将原先的16K 压缩为 1K、2K、4K、8K。对于非16K的页 ,是通过unzip_LRU列表进行管理的
通过查询状态

> show engine innodb status\G;
LRU len: 31227, unzip_LRU len: 0

注意的是,LRU列表包含 unzip_lru 的页

重做日志缓冲

Innodb 内存区内除了缓冲池,还有重做日志缓冲,首先将重做日志信息放到缓冲池中,然后通过一定的频率刷新到重做日志文件中。重做日志缓冲不需要太大,默认8M。
一下三种情况会将重做日志缓冲刷新到重做日志文件中。

  1. Master Thread 每秒钟将重做日志缓冲刷新到重做日志文件中。
  2. 事务提交时,会将重做日志缓冲刷新到重做日志文件。
  3. 重做日志缓冲池小于1/2 时。

额外内存池

额外的内存池用来对一些数据结构本身的内存进行分配,例如缓冲控制对象(buffer control block)记录的LRU,锁,等待等信息。额外的内存池不够时会从缓冲池中进行申请。因此,在申请了很大的InnoDB缓冲池时,额外的内存池也要适当的调大。通过参数innodb_additional_mem_pool_size来设置大小

你可能感兴趣的:(mysql,架构,数据库)