1、innodb体系架构
- innodb存储引擎有很多个内存块,可以认为这些内存块组成一个大的内存池
- 包含很多个后台线程,主要为Master Thread、IO Thread、Purge Thread、Page Cleaner Thread
1.1 后台线程
主要工作内容:
- 刷新内存池中的数据,保证缓冲池中缓存的数据最新
- 将已修改数据文件刷新到磁盘文件
- 保证数据库异常时InnoDB能恢复到正常运行状态
Master Thread: 主要负责合并插入缓冲、将日志缓冲刷新到磁盘、UNDO页的回收
IO Thread: 主要负责IO读写请求处理
Purge Thread: 可以指定多个innodb_purge_threads来进一步加快和提高undo回收速度
Page CleanThread: 主要负责脏页回收
1.2 内存
主要工作内容:
- 维护所有进程/线程需要访问的多个内部数据结构
- 缓存磁盘上的数据,方便快速读取,同时在对磁盘文件修改之前进行缓存
- 缓存重做日志(redo log)
1.2.1 缓冲池
缓冲池将基于磁盘存储的数据按照页的方式缓冲在内存中,缓存的数据页类型有:索引页、数据页、undo页、插入缓冲页、自适应哈希索引、innodb存储的锁信息、数据字典信息。索引页和数据页占了缓冲池大部分的空间。(缓冲池中页默认大小为16kb)
1.2.2 LRU List、Free List和Flush List
- LRU列表:通过最少使用算法管理已经读取的页
- Free列表:当数据库刚启动时,LRU列表未空,需要从Free列表中是否有可用的空闲页,若有则将Free列表该页删除,放入LRU列表
- Flush列表:当LRU列表中的页被修改后,称该页为脏页,即缓冲池的页和磁盘页数据不一致,Flush列表中的页即为脏页列表。脏页既存在于LRU列表也存在Flush列表。
1.2.3 重做日志缓冲
在写重做日志文件时,会先将数据记录到重做日志缓冲中,然后按照一定的策略将重做日志缓冲中的数据刷新到重做日志文件中。
刷新策略:
- master thread 每秒定时刷新
- 事务提交时刷新
- 重做日志缓冲池剩余空间小于1/2时刷新
2、checkpoint机制
目的:
- 缩短数据库恢复时间
- 缓冲池不够用时,将脏页刷新到磁盘
- 重做日志文件不可用时,将脏页刷新到磁盘(重做日志文件有固定大小,是循坏写入,当重做日志中的数据持续未刷新到磁盘时,会导致数据覆盖丢失)
chckpoint刷新机制参考下图
:
3、innodb引擎关键特性
3.1 change buffer
对于非唯一的辅助索引的insert、delete、update操作,并不是每一次直接操作辅助索引页,先判断索引页是否在缓冲池中,若在,则直接操作,若不在,则先放入到一个change buffer中。等未来数据被读取时,再将数据合并恢复到缓冲池中的技术。写缓冲的目的是降低读写操作的磁盘IO,提升数据库性能。
针对条件:非唯一的辅助索引
若具有唯一性,则需要对数据进行唯一性检测,则会发生从磁盘读取数据到缓冲区的离散读的操作。辅助索引的插入,若索引页不在缓冲池中,会存在大量从磁盘读取数据到缓冲区离散读的情况。
3.2 merge buffer
将change buffer中的记录合并到真正的辅助索引中
场景:
- 辅助索引被读取到缓冲池
- 该辅助索引也已无可用空间
- master thread定时合并
3.3 两次写
场景:innodb存储引擎页默认大小为16kb。若innodb存储引擎正在写入到某个16kb的页中,只写了前4kb,后发生了宕机,这种情况被称为部分写失效(重做日志解决不了该问题),故引入了两次写机制。
作用:保证数据页的可靠性
工作机制:
doublewrite由两部分组成,一部分为内存中的doublewrite buffer,其大小为2MB,另一部分是磁盘上共享表空间(ibdata x)中连续的128个页,即2个区(extent),大小也是2M。
-
当一系列机制触发数据缓冲池中的脏页刷新时,并不直接写入磁盘数据文件中,而是先拷贝至内存中的doublewrite buffer中;
-
接着从两次写缓冲区分两次写入磁盘共享表空间中(连续存储,顺序写,性能很高),每次写1MB;
-
待第二步完成后,再将doublewrite buffer中的脏页数据写入实际的各个表空间文件(离散写);(脏页数据固化后,即进行标记对应doublewrite数据可覆盖)
doublewrite架构参考下图
:
3.4 自适应哈希索引
Innodb存储引擎会监控对表上各索引页的查询,如果观察到建立哈希索引可以代理速度提升,则建立哈希索引,称之为自适应哈希索引。(自动建立)
3.5 异步IO
对IO操作可以进行合并操作
3.6 刷新邻接页
当刷新一个脏页时,innodb存储引擎会检查该页所在区的所有页,如果有脏页则一起刷新。