InnoDB的体系架构——后台线程,内存池
1、后台线程
InnoDB存储引擎是多线程的模型,因此其后台有多个不同的后台线程负责处理不同的任务
2、Master Thread
核心后台线程,主要负责将缓冲池中的异步数据刷新到磁盘,保证数据的一致性,包括脏页的刷新、合并插入缓冲(INSERT BUFFER)、UNDO页的回收等
3、IO Thread——write,read,insert buffer和log IO thread
4、查看InnoDB版本——show variables like 'innodb_version'\G;
5、查看读写线程数——show variables like 'innodb_%io_threads'\G;
6、查看IO Thread——show engine innodb status\G;、
7、Purge Thread
事务被提交后,所使用的undolog可能不再需要,因此需要PurgeThread来回收已经使用并分配的undo页。
8、Page Cleaner Thread
将脏页刷新的操作都放入到单独的线程中来完成,以减轻Master Thread的工作及对于用户查询线程的阻塞
9.内存
InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。
10.缓冲池
对于数据库中页的修改操作,首先修改在缓冲池中的页,然后再以一定的频率刷新到磁盘上。但是页从缓冲池刷新回磁盘的操作并不是在每次页发生更新时出发,而是通过一种称为Checkpoint的机制刷新回磁盘。
11、查看缓冲池——show variables like 'innodb_buffer_pool_size'\G;
缓冲池的大小直接影响着数据库的整体性能
12、从InnoDB 1.0.x版本开始,允许有多个缓冲池实例,每个页根据哈希值平均分配到不同缓冲池实例中。这样能够减少数据库内部的资源竞争,增加数据库的并发处理能力
show variables like 'innodb_buffer_pool_instances'\G;
13、缓冲池中缓存的数据页类型有:索引页,数据页,undo页,插入缓冲(insert buffer)、自适应哈希索引、InnoDB存储的锁信息、数据字典信息等。
14、缓冲池管理——LRU List、Free List、Flush List
缓冲池中页的大小默认为16KB
LRU算法将新页放入到LRU列表的midpoint位置,在默认配置下,该位置在LRU列表长度的5/8处。midpoint位置可由参数innodb_old_blocks_pct控制
show variables like 'innodb_buffer_pool_instances'\G;
15、把midpoint之后的列表称为old列表,之前的列表称为new列表
16、innodb_old_blocks_time用于表示页读取到mid位置后需要等待多久才会被加入到LRU列表的热端。
SET GLOBAL innodb_old_blocks_time=1000;
17、LRU列表用来管理已经读取的页,但当数据库刚启动时,LRU列表是空的,即没有任何的页,这是页都存放在Free列表中。当需要从缓冲池中分页时,首先从Free列表中查找是否有可用的空闲页,若有则将该页从Free列表中删除,放入到LRU列表中。否则,根据LRU算法,淘汰LRU列表末尾的页,将该内存空间分配给新的页。否则,根据LRU算法,淘汰LRU列表末尾的页,将该内存空间分配给新的页。当页从LRU列表的old部分加入到new部分时,称此时发生的操作为page made yang,另外还有一个操作为page not made young
18、show engine innodb status \G
Free buffers表示当前列表中页的数量;Database pages表示LRU列表中的数量
可能的情况是Free buffers与Database pages的数量之和不等于Buffer pool size。
因为缓冲池中的页还可能会被分配给自适应哈希索引,Lock信息,Insert Buffer等页,而这部分页不需要LRU算法进行维护,因此不存在于LRU列表中
19.InnoDB存储引擎从1.0.x版本开始支持压缩页的功能,即将原本16kb的页压缩为1KB,2KB,4KB和8KB。对于非16KB的页,是通过unzip_LRU列表进行管理的。
20.在LRU列表中的页被修改后,称该页为脏页(dirty page),即缓冲池中的页和磁盘上的页的数据产生了不一致。这时数据库会通过CHECKPOINT机制将脏页刷新回磁盘,而Flush列表中的页即为脏页列表。脏页既存在于LRU列表中,也存在于Flush列表中。
21.Checkpoing技术
为了避免发生数据丢失的问题,当前事务数据库系统普遍都采用了Write Ahead Log策略,即当事务提交时,先写重做日志,再修改页。
Checkpoint技术的目的是解决一下几个问题:
1)缩短数据库的恢复时间
2)缓冲池不够用时,将脏页刷新到磁盘
3)重做日志不可用时,刷新脏页
22.Checkpoint的种类
1)Sharp Checkpoint:发生在数据库关闭时将所有的脏页都刷回磁盘,这是默认的工作方式,通过innodb_fast_shutdown=1参数设置
2)Fuzzy Checkpoint:只刷新一部分脏页,而不是刷新所有的脏页回磁盘
Master Thread Checkpoint:主动异步刷新
FLUSH_LRU_LIST Checkpoint:保证LRU列表中需要有100个空闲页可使用,如果没有,那么InnoDB会将LRU列表尾端的页移除。如果这些页中有脏页,那么需要进行Checkpoint
Async/Sync Flush Checkpoint:指的是重做日志文件不可用的情况,这时需要强制将一些页刷新回磁盘,而此时脏页是从脏页列表中选取的
Dirty Page too much:脏页的数量太多,导致InnoDB存储引擎强制进行Checkpoint。其目的总的来说还是为了保证缓冲池中有足够可用的页。可以通过参数innodb_max_dirty_pages_pct控制
23.InnoDB 1.0.x 版本之前的Master Thread
Master Thread 具有最高的线程优先级别。其内部由多个循环(loop)组成:
主循环(loop)、后台循环(background loop)、刷新循环(flush loop)、暂停循环(suspend loop)。
Master Thread会根据数据库运行的状态在以上几种循环中进行切换。
Master Thread——Loop主循环
包括两大部分的操作:每秒钟的操作和每10秒的操作。
24.InnoDB关键特性
1)插入缓冲(Insert Buffer)
Insert Buffer
在InnoDB存储引擎中,主键是行唯一的标识符。通常应用程序中记录的插入顺序是按照主键递增的顺序进行插入的。因此,插入聚集索引一般是顺序的,不需要磁盘的随机读取。
对于非聚集索引的插入或更新操作,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若在,则直接插入;若不在,则先放入到一个Insert Buffer对象中。然后再以一定的频率和情况进行Insert Buffer和辅助索引页子节点的合并操作,这时通常能将多个插入合并到一个操作中,这就大大提高了对于非聚集索引插入的性能。
Insert Buffer的使用需要同时满足以下两个条件:
索引是辅助索引,索引不是唯一的。
目前Insert Buffer存在一个问题是:在写密集的情况下,插入缓冲会占用过多的缓冲池内存。
Change Buffer:Innodb 存储引擎可以对DML操作(INSERT,DELETE,UPDATE)都进行缓冲
Insert Buffer是一棵B+树,因此其也由叶节点和非叶节点组成。非叶节点存放的是查询的search key(键值)
search key的构造: space | marker | offset
space表示待插入记录所在表的表空间id,在InnoDB存储引擎中,每个表有一个唯一的space id,可以通过space id查询得知是哪张表。
marker是用来兼容老版本的Insert Buffer。
offset表示页所在的偏移量。
Merge Insert Buffer的操作可能发生在以下几种情况下:
辅助索引页被读取到缓冲池时
Insert Buffer Bitmap页追踪到该辅助索引页已无可用空间时
Master Thread
2)两次写(Double Write)
如果说Insert Buffer带给InnoDB存储引擎的是性能上的提升,那么doublewrite带给InnoDB存储引擎的是数据页的可靠性。
3)自适应哈希索引(Adaptive Hash Index)
4)异步IO(Async IO)
5)刷新领接页 (Flush Neighbor Page)