flushed_to_disk_lsn
记录刷新到磁盘的redo log 日志量
文章插图
当存在新的日志写入到log buffer的时候 , 首先lsn(log squence number记录当总共写入的redo 日志量)会增大 , 但是
flushed_to_disk_lsn
大小不变(因为没刷盘)随着log buffer中的内容刷新到磁盘 , flushed_to_disk_lsn
将随之增大 , 当flushed_to_disk_lsn = lsn
的时候说明所有log buffer中的日志都刷新到了磁盘6.buffer pool 中flush 链表中的lsnMTR是对底层页面的一次原子访问 , 在访问过程中会产生一组不可以分割的redo log , 在MTR结束的时候会把这一组redo log记录到log buffer中 。除此之外在MTR结束的时候还需要:
把MTR执行过程中修改的页面加入到Buffer pool中的flush链表中
, 毕竟刷新脏页到磁盘是buffer pool的任务 。当这个页面第一次被修改的时候就会将其对应的控制块插入到flush 链表头部 , 后续再次修改不会移动控制块 , 因为其已经在flush 链表中 , 所有说flush 链是按照页面第一次修改的时间进行排序的 , 在这个过程中会记录两个重要的属性到脏页的控制块中:
- oldest_modification
第一次修改修改buffer pool某个缓冲页(先把页读到buffer pool的缓冲页 , 然后进行修改)时 ,记录下修改该页面MTR开始时对应的lsn
(注意这个开始时)
- newest_modification
每次修改页面 , 都会记录下修改该页面MTR结束时的lsn
,该属性记录最近一次修改后对应的lsn
文章插图
MTR2后续修改了页B和页C , 页B , 页C最开始不在flush链表中 , 背修改后加入到链表的头部 , 也就是说 , 越靠近头部 , 修改的时间就越晚 , 如下:
文章插图
如果此时在flush链表中的页被修改 , 只需要更新newest_modification即可 。flush链表按照第一次被更新时候的lsn排序 , 也就是按照oldest_modification进行排序 , 多次修改位于flush链表中的页只会更新其newest_modification
7.checkpoint由于redo log日志文件文件是有限的 , 所有需要循环使用redolog 日志文件组中的文件 。redo log存在的目的是系统崩溃后恢复脏页 , 如果对应的脏页已经刷新到磁盘中 , 那么即使系统崩溃 , 重启之后页不需要使用redo log恢复该页面看 , 对应的redo log日志也没存在的必要了 , 占用的磁盘空间可以进行重复使用 , 被其他redo log日志覆盖 。那么如何判断哪些redo 日志占用的磁盘空间可以覆盖昵 , 其对应的脏页已经刷新到磁盘了昵?
innodb使用
checkpoint_lsn记录可以被覆盖的redo log日志总量
文章插图
假如页A已经被刷新到磁盘了 , 那么页A对应的控制块会从flush链表中移除 , MTR1生成的日志可以被覆盖了 , 就进行一个增加
checkpoint_lsn
的操作 , 这个过程称作执行一次checkpoint(刷新脏页到磁盘和执行一次checkpoint是两回事 , 通常是不同线程上执行的 , 并不意味着每次刷新脏页的时候都会执行一次checkpoint)
经验总结扩展阅读
- MySQL的下载、安装、配置
- 我的Vue之旅 09 数据数据库表的存储与获取实现 Mysql + Golang
- 「MySQL高级篇」MySQL之MVCC实现原理&&事务隔离级别的实现
- Mysql InnoDB Buffer Pool
- 「MySQL高级篇」MySQL锁机制 && 事务
- 【MySQL】Navicat15 安装
- 「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景
- 「MySQL高级篇」MySQL索引原理,设计原则
- MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。
- MySQL 全局锁、表级锁、行级锁,你搞清楚了吗?