InnoDB体系架构(后台线程和内存池)(读MySQL技术内幕-InnoDB存储引擎)
1.InnoDB有多个后台线程(mysql引擎自己的)和内存块(内存块组成了一个大的内存池)
内存池:缓存磁盘的数据
后台线程:保证内存中缓存的是最新数据,并将数据刷新到磁盘中
、
后台线程:
Master Thread (将数据缓冲池中的数据异步刷新到磁盘,包括脏页的刷新,合并插入缓冲,UNDO页的回收)
脏页:内存数据页和磁盘数据页不一致时,称这个内存页为脏页,一致的内存页就是干净页
合并插入缓冲:https://blog.csdn.net/qq_39101581/article/details/87276614
UNDO页:日志,用于存放记录修改前的值(表中一个值从2修改到3,UNDO存放2,当修改出现异常时,用日志来回滚)
IO Thread
大量使用AIO(Async IO)处理IO请求,提高性能。
此线程主要负责IO请求的回调,一共有四种(10个)IO Thread ,分别为write,read,insert buffer 和log IO thread,windows可以调整数量,Linux不可
show engine innodb status;(产看mySql里面的IO线程)
Purge Thread
事务提交后,此线程用来回收undo页,减轻Master Thread工作量(可自己在配置文件中设置多个Purge Thread)
Page Cleaner Thread
脏页的刷新,减轻主线程的负担
内存:
将磁盘读到的页存放到缓冲池中,这个过程叫:将页“FIX”到缓冲池中
修改数据时:先修改缓冲池的页,在以一定的频率刷新到数据库(不是立即,通过Checkpoint机制刷新到磁盘)
下图为缓冲池的大小(以字节为单价,共8M)
缓冲池中缓存的数据页类型有:索引页,数据页,undo页,插入缓冲(insert buffer),自适应哈希索引,锁信息,数据字典等。。
且现在允许多个缓冲池实例来操作缓冲池,提高并发性能 (下图值设置大于一)
LRU List (Latest recent Used),Free List 和 Flush List
Innodb的LRU算法(midpoint insertion strategy算法)(最近最少使用)管理缓冲池:最频繁使用的页在LRU列表前端,最少使用的页在尾端,并在LRU列表中加midpoint位置(默认LRU列表5/8位置,位置由innodb_old_blocks_pct参数控制(下图)),最新访问的页,不是加在首部,而是加在midpoint位置,
默认值:37(尾端3/8位置),这个位置之后的叫old列表,之前的叫new列表(最新最活跃数据)
最朴素的LRU算法的缺点:直接将读取的数据放在首部,当进行数据库的扫描操作时,需要访问数据库中的许多页,甚至全部页,而这些数据仅仅是这一此sql操作中需要,不是真正的热点数据,那么真正的热点数据就被刷出缓存了,下次访问就需要在磁盘中查找,Innodb用innodb_old_blocks_time参数做控制,表示页读取到mid位置后需要等待多久才会加入到LRU列表的热端(就是说数据已经读到LRU列表的mid位置后,不会立即把原来的5/8数据刷掉,会等一段时间,因为这段时间是有可能用到真正的热数据的,时间过了又没有其他sql操作,就把之前的LRU数据替换掉了,有的话就不替换了)
LRU列表只管理已经读取的页,则数据刚启动时为Null,此时页都放在Free列表中。需要从缓冲池中分页时,先查看Free有无空闲页,有则给LRU,没有的话根据LRU算法,淘汰LRU尾端的页,分给新页
page made young操作:LRU列表old-->new
page not made young操作:因为innodb_old_blocks_time的设置导致没有old--->new
show engine innodb status;查看LRU列表和Free列表的使用情况和状态(不是当前状态,过去时间范围内,下图)
unzip_LRU列表:管理压缩的数据页,16KB--->可能压缩到为:1KB,2KB,4KB,8KB。unzip_LRU对不同大小的页是分开管理的
内存分配(伙伴算法):如在缓冲池中需要4KB的页
1.检查4KB的unzip_LRU列表,查看是否有空闲页,有则直接使用
2.没有的话,查看8KB的unzip_LRU列表,查看是否有空闲页,有的话分成2个4KB的页,存放在unzip_LRU列表
3.还是没有的话,从LRU列表中申请一个16KB的页,分成1个8KB,2个4KB的页,分别放入对应的unzip_LRU列表
Flush列表中即为脏页列表,但脏页即存在LRU列表中,也存在Flush列表中,LRU列表管理缓冲池中页的可用性,而Flush列表管理脏页的刷新回磁盘,互不影响。
重做日志缓冲(redo log buffer)
innodb先将重做日志信息放在这个缓冲区,再按一定频率刷新到重做日志文件中
下面三种情况会将重做日志缓冲刷新到磁盘的日志文件中:
1.Master Thread每秒刷新一次
2.每个事务提交时会刷新一次
3.日志缓冲剩余空间小于1/2时,会刷新一次
额外内存池
类似于一些特殊的对象的内存是需要到额外内存池中申请的
本文地址:https://blog.csdn.net/qq_35970057/article/details/107368333