昨天和公司技术总监聊过之后,感觉自己基础还不是很扎实,所以读一读数据库底层实现的书籍,特做此读书笔记(会不断更新哦~):
第一章 MySQL体系结构和存储引擎
- MySQL单进程多线程和SQL Server类似。Oracle多进程。
- MySQL体系架构图
第二章 InnoDB存储引擎
InnoDB体系架构
- InnoDB后台线程
- Master Thread负责将缓冲池中的数据异步刷新到磁盘。
- IO Thread负责异步IO请求的回调处理。read thread线程数4个,write thread线程数4个。
- Purge Thread负责事务被提交后,回收已经使用并分配的undo页。
- Page Cleaner Thread负责脏页的刷新操作。
缓冲池
新是触发,而是通过一种称为Checkpoint的机制刷新回磁盘。同样这也是为了提高数据库的整体性能。
- 关于InnoDB缓冲区的管理
- 通过LRU(Lastest Recent Used)算法进行管理,最频繁使用的页在LRU列表的前端,而最少使用的页在LRU列表的尾端。当缓冲池不能存放新读取到的页时,将首先释放LRU列表中尾端的页。
- 算法优化(midpoint insertion strategy)新读取到的页,虽然是最新访问的页,但并不是直接放入到LRU列表的首部,而是放入到LRU列表的midpoint位置。
- innodb_old_blocks_time用于表示页读取到mid位置后需要等待多久才会被加入到LRU列表的热端。
- 当需要从缓冲池分页时,首先从Free列表中查找是否有可用的空闲页,如有则将该页从Free列表中删除,放入到LRU列表中,否则,根据LRU算法,淘汰LRU列表末尾的页,将该内存空间分配给新的页。当页从LRU列表的old部分加入到new部分时,称此时发生的操作为page made young;而因为innodb_old_blocks_time的设置而导致页没有从old部分移动到new部分的操作称为page not made young。
- buffer pool hit rate表示缓冲区的命中率,通常该值不应该小于95%,如果小于95%,用户需要观察是否是由于全表扫描引起的LRU列表被污染的问题。
- LRU中的页包含了unzip_LRU列表中的页(压缩页),在unzip_LRU列表中对不同压缩页大小的页进行分类管理,内存分配方法如下。
- 在LRU列表中的页被修改后,称该页为脏页(dirty page),即缓冲池中的页和磁盘上的页的数据产生了不一致,脏页既存在于LRU列表中,也存在于Flush列表中。LRU列表用来管理缓冲池中页的可用性,Flush列表用来管理将页刷新回磁盘,二者互不影响。