MySQL体系结构
从上图可以看出,主要是这几个
- 连接池组件
- 管理服务和工具组件
- SQL接口组件
- 查询分析器组件
- 优化器组件
- 缓冲组件
- 插件式存储引擎
- 物理文件
其中比较重要的就是这个插件式的存储引擎,这个引擎完全是基于表的,而不是基于整个数据库。
InnoDB的优点
- 插入缓冲:对于非聚集索引的插入或更新操作不是每次直接插入到索引页,先判断插入的非聚集索引页是否在缓冲池中,若在,直接插入,若不在,先放入插入缓冲对象中。再用一定的频率对插入缓冲和辅助索引页进行合并操作。
- MVCC高并发:支持行锁,每次删除不直接删除数据,而是去标记这个数据无效。
- next-key locking 避免幻读。
- 支持事务,保证ACID。
- 支持崩溃后的安全恢复。
InnoDB体系结构
一图胜千言,上面就是Innodb存储引擎的体系架构。
后台线程
- 刷新内存池中的数据,保证缓冲池中的内存缓冲是最近的数据。
内存池
- 存储所有进程/线程需要访问的多个内部数据结构
- 缓存磁盘上的数据,方便快速读取
- redo log的缓冲
- 后台线程
Master Thread
主线程,用于将缓冲池中的数据异步刷新到磁盘,保证数据的一致性。IO Thread
使用大量Async IO来提高数据库性能。这些线程的主要工作就是负责IO请求的回调。1.0.x版本之后,分别有4个write和read,1个insert buffer和1个log thread。
Purge Thread
事务提交之后其undolog可能不在需要,因此需要PurgeThread来回收已经使用并分配的undo页。Page Cleaner Thread
1.2版本引入,目的是减轻主线程的工作量。
- 内存池
- 缓冲池
其实就是一块内存区域,按照页的方式进行管理。在数据库读取页的时候,首先判断此页是否在缓冲池中,若没有,则读取的时候顺便把它放到缓冲池中。而脏页的回写遵循checkpoint机制。
缓冲池中不光是数据和索引,更有自适应哈希索引,所信息,数据字典信息等等。 - LRU List/Free List/Flush List
需要注意的是在进行LRU的时候,每次新的页不是直接插在表头,而是5/8的位置,为什么?因为某些SQL操作例如数据的扫描和索引等,需要访问表中的甚至全部页,而这些都不是热点数据,如果插在头部会淘汰热点数据。
还有一个问题,什么时候会认为这些数据是热点数据?mysql设置了一个参数,只要超过这个时间,就会被移到热端。
还有一点是脏页可同时存在于LRU list和Flush list中。
redo log缓冲
额外的内存池
对一些数据和结构本身的存储,必要的时候需要设置大一点
- checkpoint技术
设置这个技术的目的就是为了协调cpu和磁盘的速度,刷新频率不能太快,太快导致性能变差,并且如果从缓冲刷到磁盘宕机了,数据就丢失了。为了避免这个情况,使用Write Ahead Log策略,事务提交时,先写重做日志,再修改页,这样可以通过redo log来恢复。这也是事务ACID中D的要求。
综合来看,checkpoint技术解决下面几个问题:
- 缩短数据库恢复时间(只需redo 检查点之后的数据)。
- 缓冲池不够时,将脏页刷新到磁盘。
- redo log不可用时,刷新脏页(redo log满了)。
checkpoint分为sharp和fuzzy两种,第一种是把所有脏页刷回磁盘,第二种有下面好几种情况:
- 主线程检查点:每秒或者没十秒从缓冲池刷一定比例的脏页回磁盘。
- Flush/LRU 检查点:保证列表有一定比例的空闲项。
- Async/Sync checkpoint:redo日志不可用时刷新。
- 主线程工作方式
主线程内部由几个循环组成
- 主循环
- 每1s
- 日志缓冲刷新到磁盘
- 合并插入缓冲
- 至多100个脏页回写(后面版本改成以磁盘IO吞吐量来定)
- 如果没有活动,切换到后台循环
- 每10s
- 刷新100个脏页
- 合并5个插入缓冲
- 日志缓冲回写
- 删除无用undo页
- 刷新100个或10个脏页
- 每1s
- 后台循环
- 删除无用undo
- 合并20个插入缓冲
- 跳回主循环
- 不断刷新100个页,跳转刷新循环
- 刷新循环
- 暂停循环
- 插入缓冲
对于非聚集索引的插入或者更新,不是直接插入到索引页, 而是先放入插入缓冲对象中。再按照一定的频率对插入缓冲和非聚集索引节点进行合并操作。
- 两次写(double write)
两次写由两个部分组成,一部分是内存中的doublewrite buffer(2MB)。另一部分是物理磁盘上共享表空间中连续的128页(2MB)。
对缓冲池脏页刷新时:
- 不立马写磁盘,使用memcpy将脏页复制到buffer中
- 分两次,每次先将buffer的1MB写入共享表空间,调用fsync函数同步磁盘
- 自适应哈希索引(AHI)
InnoDB会监控对表上索引页的查询,如果观察到简历哈希索引可以带来速度提升,会建立哈希索引。
建立哈希索引的条件是:
- 通过某模式访问100次
- 页通过该模式访问了(页中记录/16)次