mysql 8.0 源码笔记:REDO日志(3)

本文解析了MySQL 8.0.22社区版中redo日志的写入流程,包括何时刷盘,以及checkpoint机制的作用,重点介绍了如何判断并执行checkpoint操作,以及checkpoint信息的记录方式。
摘要由CSDN通过智能技术生成

版本

mysql-8.0.22 社区版

源码

结合源码来介绍redo日志的各个模块。

redo日志的写入

写入系统磁盘

redo日志刷盘是将所有的redo文件进行fsync,确保系统缓存中的redo日志内容存储到磁盘上。

redo刷盘由用户线程执行、或者系统后台线程执行。刷盘接口为统一的接口、

相关变量定义
log_t *log_sys
| flushed_to_disk_lsn		//当前磁盘刷新到的位置

刷新磁盘

刷新磁盘的源码如下:

log_flush_low
| const lsn_t last_flush_lsn = log.flushed_to_disk_lsn.load();
| const lsn_t flush_up_to_lsn = log.write_lsn.load();

  // 如果flush_lsn 小于 write_lsn 就进行刷盘
| if (last_flush_lsn < flush_up_to_lsn)
|  fil_flush_file_redo()
|  | // 对所有的redo文件进行刷盘
|  | for (auto &file : space->files) 
|  |   os_file_flush(file.handle);


redo的checkpoint

redo日志的checkpoint机制是为了保证redo日志的复用。在WAL机制下,redo日志优先落盘,数据页后续异步后台线程落盘。当数据页落盘之后,redo日志便可以回收复用。

相关变量定义
log_t *log_sys
| last_checkpoint_lsn		//当前磁盘checkpoint到的位置

| checkpoint_buf            // 用来更新redo的header的buffer

| recent_closed				//判断当前可以刷脏的最大LSN
checkpoint

判断可以checkpoint的最大LSN

log_update_available_for_checkpoint_lsn
  1. 当前可以刷脏的最大LSN, 
| log_buffer_dirty_pages_added_up_to_lsn(log);
  | recent_closed.tail()

  2. flush list中最小的lsn向后退一个recent_closed.capacity()
| lsn_t lwm_lsn = buf_pool_get_oldest_modification_lwm();

  3. flush_lsn 和 checkpoint_lsn取小
| log.flushed_to_disk_lsn.load() // log.last_checkpoint_lsn.load()

  4. 取三项中最小的LSN最为本次可以 checkpoint的LSN
| log.available_for_checkpoint_lsn = oldest_lsn;

recent_closed是在将数据页加入flush_list时使用,原理同write_recnet类似,用以保证recent_closed.tail()之前的数据页都已经加入到flush_list中,在刷脏时不会有遗漏的情况。

checkpoint

log_consider_checkpoint(log);
  // 先将dynamic_metadata
| dict_persist_to_dd_table_buffer();
| log_checkpoint(log);
| | log_files_write_checkpoint(log, checkpoint_lsn);
  | | // 生成一个checkpoint_no
  | | checkpoint_no = log.next_checkpoint_no.load();
  
      // 将checkpoint相关信息写入buffer
  | | mach_write_to_8(buf + LOG_CHECKPOINT_NO, checkpoint_no);
  | | mach_write_to_8(buf + LOG_CHECKPOINT_LSN, next_checkpoint_lsn);
	
	  // 写入系统缓存并刷盘
  | | err = fil_redo_io( IORequestLogWrite,
  | | log_fsync();

redo使用两个BLOCK来记录checkpoint相关信息,根据checkpoint_no来决定使用哪一个,分别记录在redo日志第2个和第4个BLOCK中,两个checkpoint的block交替使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值