缓冲池

mysql使用 innodb作为存储引擎的表来说 数据都是以页的形式存储在表空间里  我们知道磁盘访问速度很慢,所以为了提高速度 当访问某个页上面的数据时  先将这个页加载到内存中 缓存起来就可以对数据进行读写操作了    下次再次访 就不需要再次去磁盘里找了 提高效率   这个内存就是buffer pool 缓存池

mysql-缓冲池

Buffer pool组成

这个是innodb整体结构   

buffer pool中包含了  insert buffer , 索引和数据,锁信息等

buffer pool默认的缓存页和磁盘页大小一样 16k 为了更好的管理这些页  给每个页设置一个控制信息块  每个页对应一个控制块 这个控制块记录了 该页所属的 表空间号 页号,缓存页在bufferpool中的地址等信息 结构如下

mysql-缓冲池

free 链表

free链表 是记录那些 空闲的缓存页的  把空闲的缓存页对应的控制块作为一个节点 插入到free链表中  每当从磁盘中加到一个页到内存中的时候  就从这个链表中取出一个空闲缓存页  先将磁盘中的这个页的信息(表空间号 页号)写入到 这个空闲缓存页所对应的控制块中  然后将这个节点从链表中pop出,表示这个页已经被使用了

mysql-缓冲池

flush链表

如果对一个缓存页上的某个数据进行修改 那么缓存页和磁盘页上的数据就不一样了 这个页 就称之为脏页,那么如何处理脏页呢,

最简单的办法就一旦产生脏页 就将数据同步到磁盘上,但是缺点是 产生大量的磁盘io,所以每次修改缓存页里的数据时 不着急每次都同步数据 而是在未来的某个时间点进行刷盘

如果不立刻同步数据到磁盘的话 那么bufferpool 中的缓存页 有的是脏页有的不是脏页 如何判断哪些是脏页哪些不是呢  flush链表就是来干这个事的 

innodb修改数据的时候 是write ahead log 机制  即先写log 在写数据 目的是为了保证操作的持久化 大概是先将对数据的改动 写入到 log buffer中 然后再在内存中记录数据的变化 写入log buffer 后 就会将这个缓存页对应的控制块 加入到 flush链表上 表示这个页 就是一个脏页了 后面刷新脏页的时候 就知道哪些页是脏页了  flush链表结构如下

mysql-缓冲池

LRU链表

bufferpool 大小是有限制的  如果内存不够用了 那么应该淘汰一些不怎么经常被访问的缓存页  把这些就的缓存页从bufferpool中删除 再加载新的页到bufferpool中   那么如何计算 哪些页最近频繁使用 哪些页最近很少使用呢 LRU链表就是这个作用 

mysql-缓冲池

刷新脏页到磁盘

之前提过 缓冲池中产生了脏页 那么是如果将脏页同步到磁盘中的呢 分几种情况

1,redo日志满了  那么系统会停止所有更新操作 checkpoint往前推进 对应的所有脏页要flush到磁盘上

2,bufferpool 不够用了 那么要先将脏页写入到磁盘.如果没有可用的缓存页了 那么会将LRU链表尾部淘汰一些页 如果这些页是脏页 那么就刷新到磁盘变成干净的页 才能被复用

3,系统空闲的时候 后台进程会刷新脏页

double write

上文说的是刷新脏页的时间点 那么具体是怎么刷新的呢 

mysql数据页大小16k 但是磁盘文件一个页大小4k那么将16k的文件写入到磁盘里 肯定不是一次就写完的  如果写入过程中数据库了突然断电 可能造成写入不完整 造成数据页损坏,这样情况下 即使有redolog 也无法恢复数据了 因为redolog中记录的是对页修改,如果数据页损坏了 就无法通过redolog恢复了

mysql-缓冲池

所以为了保证数据页正确的写入 引入了 double write机制 

mysql-缓冲池

double write 分两部分 一个是内存中的 doublewrite buffer(2m)  和磁盘中 共享表空间里的 128个连续的页 也是2m 脏页从flush链表刷新时  先使用调用memcopy方法 将脏页拷贝到 doublewrite buffer中 然后 分两次 每次1m将doublewrite buffer 刷新到磁盘的doublewrite区  之后再掉调用fsync方法不同到磁盘中

redolog 刷新到磁盘

上文提到 更新操作是wal 先写日志再写内存 为了保证事务的持久性 log buffer里的 redolog必须要刷新到磁盘里,刷新的机会点 有4种情况

1,log buffer 存储空间不足时,log buffer 空间是有限的 当relolog日志量超过log buffer总容量的一半时 就需要将这些日志刷新到磁盘上

2,事务提交时,

3,后台线程 刷新

4,正常关闭服务时

mysql-缓冲池

相关文章: