mysql 中的 redo log 与 binlog

一条 sql 更新语句也会跟查询语句一样,经过连接层、解析层、优化层、执行层 (可看 mysql 架构)

但是除此之外,更新还涉及了两个重要的日志模块:redo log(重做日志)、binlog(归档日志)

redo log

redo log 是引擎层的日志

mysql 使用了 WAL 技术(Write-Ahead-Logging),它的关键点就是先写日志,再写磁盘。

如果每一次更新操作都需要从磁盘中找到对应的记录,然后对记录进行修改,就会产生很高的 IO 成本以及查找成本,严重的影响效率,WAL 就是为了解决这种情况而生的

具体的说,一条记录需要更新时,InnoDB 存储引擎会先将记录放到 redo log 中并且更新内存,这时更新语句已经算执行完毕了,然后在适当的时候 InnoDB 存储引擎会进行磁盘的修改,一般都是在空闲时进行磁盘读写

但是 redo log 是有一定的大小的,比如配置 4 个文件,每个文件大小 1GB,那么总共就可以记录 4GB 的记录,它的作用原理类似于下图,是一个环,空间可以循环的利用

image-20220114115333530

write pos 与 check pos分别代表写的位置和要擦除的位置,它们之间是剩余可以用来存储的空间,如果write pos 追上了 check pos 这就代表 redo log 已经写满,需要先擦除一些记录写到磁盘中

redo log 保证了 mysql server 在崩溃时不会丢失记录,这个能力被称为 safe-crash ,假如没有 redo log 就可能导致在查找某个要修改的记录时发生了断电,内存中数据消失,此时更新操作也就进行失败了

binlog

相比于 redo log,binlog 是 mysql server 层的日志同时不具有 safe-crash 的能力

下面列举 redo log 与 binlog 的不同点:

  • redo log 是 InnoDB 特有的,是引擎层的;binlog 是所有引擎都能用的,是 server 层的
  • redo log 记录的是物理日志,及对某一个数据页进行修改;binlog 记录的是逻辑日志,及对某条记录进行了什么修改
  • redo log 是循环写的,大小固定;binlog 是追加写的,大小达到上限会创建新的文件

了解它们的不同后,我们接下来看看一条更新语句是如何执行的:

  1. 执行器先访问引擎找到要修改的记录,如果记录在内存中则直接返回,不在内存中则在 b+ 树中搜索记录,然后存到内存中并返回
  2. 执行器拿到记录并对记录进行修改,修改后的记录通过引擎暴露的接口写该数据
  3. 引擎会更新内存中的记录
  4. 引擎写入 redo log ,并将记录状态置为 prepare,然后告知执行器事务处于可以提交的状态
  5. 执行器收到反馈后生成 binlog 并追加写入
  6. 执行器调用引擎提交事务接口,引擎将 redo log 的状态置为 commit

此时一条更新语句就执行完成了

那么 binlog 的作用究竟是什么呢?

其实 binlog 就是用来恢复数据库状态的,举个例子:

假如你昨天不小心删除了两条数据,你想要数据库恢复到删除这两条数据之前的状态,那么你就可以找到离这次失误前最近的一次数据库全量备份(在主从复制时还有增量备份,全量备份就是把整个数据库备份下来,增量备份是只备份主从中不同的)并把它复制到临时数据库上,然后将 binlog 取出重新放到失误前的时间上,这样临时数据库就会和误删前的状态相同了

两阶段提交

从上文步骤中 4、5、6 可以发现,redo log 的提交分成了两步,这么做其实是为了保证两种日志的一致性

假如我们 ”一阶段提交“:

  • 先提交 redo log,再提交 binlog:在 redo log 提交后发生断电,此时 binlog 会少了一次更新的记录,系统恢复后数据库会根据 redo log 将数据更新,此时用 bin log 恢复的临时数据库会少了这一次更新,原数据库却被更新了
  • 先提交 binlog,再提交 redo log:在 binlog 提交后发生断电,此时 redo log 中没有更新的记录,系统恢复后断电时那条数据不会被更新,此时用 bin log 恢复的临时数据库会有这一次更新,愿数据库却没有被更新

这两种情况都会导致原数据库与恢复出来的数据库不一致

小结

  • innodb_flush_log_at_trx_commit 设置为1:每次事务都将 redo log 更新到磁盘
  • sync_binlog 设置为1:每次事务都将 binlog 更新到磁盘
  • redo log 记录这个页 “做了什么改动”
  • Binlog有两种模式,statement 格式的话是记sql语句, row格式会记录行的内容,记两条,更新前和更新后都有。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值