2.1 Innodb的后台线程
- Master Thread *1 —— 详细介绍
- IO Thread *4+4 —— 4个write,4个read,1个insert buffer,1个log thread
- Purge Thread(资源清理) *1
- Page Cleaner Thread(刷新脏页) *1
Master Thread 主线程
四个循环:
主循环分成两部分,一部分是每一秒钟要做的事情,另一部分是每10秒钟要做的事情:
| 工作 | 解释 | 是否必须 | 属于 |
| 重做日志缓冲(Redo log ) 刷新到文件 |
每秒:刷新重做日志缓冲到磁盘 每10秒:同上 |
总是 总是 |
主线程 |
| 合并插入缓冲(insert buffer) | 每秒:如果这一秒IO次数少,则执行 每10秒:合并最多5个 insert buffer background:合并20个insert buffer |
可能 总是 总是 |
主线程 |
| 每秒:自适应刷新一定数量脏页到磁盘 每10秒:如果10秒内IO次数<200,刷新100个到磁盘 每10秒:比例>70%,刷新100个;<70%,刷新10%的脏页 |
可能 可能 总是 |
Page Cleaner Thread | |
| 每10秒:最多删(默认)20个Undo页 background:删除无用Undo页 |
总是 总是 |
Purge Thread |
2.2 内存
- 缓冲池
- 重做日志缓冲
- 额外的内存池
缓冲池
- 主要存储:数据页(叶子节点)+索引页(非叶子节点)
- 次要存储:undo页+插入缓冲+自适应哈希索引+innodb锁信息+数据字典
- 如何管理:改进的LRU算法(队列首最频繁,尾部LRU,插入时midpoint位置)
- LRU队列:管理缓冲池中页的可用性
- Flush队列:记录脏页(即LRU队列中被修改过,与硬盘不一致的页)
其他:1.0.x版本后允许有多个缓冲池实例,每个页根据哈希分配
重做日志缓冲:innodb特有,先将重做日志信息放入该buffer,再以一定频率刷新到文件中
刷新到文件条件:1. Master Thread每秒刷一次,每10秒刷一次 2. 事务提交 3.重做日志缓冲 空间<1/2
2.3 Checkpoint技术
将缓冲池中的脏页刷新回磁盘
- Sharp Checkpoint:关闭数据库时全部刷新回磁盘
- Fuzzy Checkpoint
- Master Thread:主线程相关,每秒或10秒刷新
- FLUSH_LRU_LIST:LRU列表空间不够时(<100),将尾端不常用的移除。如果存在脏页,则刷新
- Async/Sync Flush:保证重做日志的循环可使用性
- Dirty Page too much:脏页比例>75%,刷新到磁盘
2.4 Innodb特性
- 插入缓冲
- 二次写
- 自适应哈希
- 刷新邻接页
插入缓冲:
解决的问题:对于该非聚集索引来说,叶子节点的插入不再有序,这时就需要离散访问非聚集索引页,插入性能变低。
机制:当插入非唯一的辅助索引时生效,对于非聚集类索引的插入和更新操作,不是每一次都直接插入到索引页中,而是先插入到内存中。
具体做法:如果该索引页在缓冲池中,直接插入;否则,先将其放入插入缓冲区中,再以一定的频率和索引页合并,这时,就可以将同一个索引页中的多个插入合并到一个IO操作中,大大提高写性能。
内部实现原理:在共享表空间中维护了B+树
两次写:
刷新脏页时不直接写入磁盘,先写入 doublewrite buffer中,再写入表空间的double write区域内,最后写入文件,宕机时先从double write恢复。
自适应哈希:
对热点查询自适应建立哈希索引
刷新邻接页:
对于传统固态硬盘,刷新脏页时,观察其临接是否也为脏页,如果是则一起刷新,省去磁盘寻道等时间。
对于固态硬盘,不需要。