mysql8.0源代码解析_源码解读:MySQL 8.0 InnoDB无锁化设计的日志系统

原标题:源码解读:MySQL 8.0 InnoDB无锁化设计的日志系统

作者介绍

张永翔,现任网易云RDS开发,持续关注MySQL及数据库运维领域,擅长MySQL运维,知乎ID:雁南归。

MySQL 8.0中一个重要的新特性是对Redo Log子系统的重构,通过引入两个新的数据结构recent_written和recent_closed,移除了之前的两个热点锁:log_sys_t::mutex和log_sys_t::flush_order_mutex。

这种无锁化的重构使得不同的线程在写入redo_log_buffer时得以并行写入,但因此带来了log_buffer不再按LSN增长的顺序写入的问题,以及flush_list中的脏页不再严格保证LSN的递增顺序问题。

本文将介绍MySQL 8.0中对log_buffer相关代码的重构,并介绍并发写log_buffer引入问题的解决办法。

一、MySQL Redo Log系统概述

Redo Log又被称为WAL ( Write Ahead Log),是InnoDB存储引擎实现事务持久性的关键。

在InnoDB存储引擎中,事务执行过程被分割成一个个MTR (Mini TRansaction),每个MTR在执行过程中对数据页的更改会产生对应的日志,这个日志就是Redo Log。事务在提交时,只要保证Redo Log被持久化,就可以保证事务的持久化。

由于Redo Log在持久化过程中顺序写文件的特性,使得持久化Redo Log的代价要远远小于持久化数据页,因此通常情况下,数据页的持久化要远落后于Redo Log。

每个Redo Log都有一个对应的序号LSN (Log Sequence Number),同时数据页上也会记录修改了该数据页的Redo Log的LSN,当数据页持久化到磁盘上时,就不再需要这个数据页记录的LSN之前的Redo日志,这个LSN被称作Checkpoint。

当做故障恢复的时候,只需要将Checkpoint之后的Redo Log重新应用一遍,便可得到实例Crash之前未持久化的全部数据页。

InnoDB存储引擎在内存中维护了一个全局的Redo Log Buffer用以缓存对Redo Log的修改,mtr在提交的时候,会将mtr执行过程中产生的本地日志copy到全局Redo Log Buffer中,并将mtr执行过程中修改的数据页(被称做脏页dirty page)加入到一个全局的队列中flush list。

InnoDB存储引擎会根据不同的策略将Redo Log Buffer中的日志落盘,或将flush list中的脏页刷盘并推进Checkpoint。

在脏页落盘以及Checkpoint推进的过程中,需要严格保证Redo日志先落盘再刷脏页的顺序,在MySQL 8之前,InnoDB存储引擎严格的保证MTR写入Redo Log Buffer的顺序是按照LSN递增的顺序,以及flush list中的脏页按LSN递增顺序排序。

在多线程并发写入Redo Log Buffer及flush list时,这一约束是通过两个全局锁log_sys_t::mutex和log_sys_t::flush_order_mutex实现的。

二、MySQL 5.7中MTR的提交过程

在MySQL 5.7中,Redo Log写入全局的Redo Log Buffer以及将脏页添加到flush list的操作均在mtr的提交阶段中完成,简化后的代码为:

b0d879144244e290da52e5495e483bc3.png

MySQL官方博客中有一张图可以很好的展示了这个过程:

87626215817f272fdafd5edc0cf44d7c.png

三、MySQL

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值