MySQL日志binlog和redo log区别

MySQL binlog简介

MySQL中有两类日志:binlog和redo log,分别有不同的作用和解决问题。binlog是归档日志,在MySQL server层的日志,适用于所有存储引擎,redo log是innodb特有日志用于crash-safe时恢复数据。

binlog和redo log的区别

binlog是server层日志,出现比redo更早,通常用于数据备份和归档。它的日志内容也是记录的DDL和DML的逻辑SQL,即差不多是SQL原句。写入方式是顺序写入,即根据配置会一直开一个新文件写入。日志格式有3种:statment、row、mixed。都分别有优劣势,其中最常用的是row。

redo log是innodb层日志,专门用于crash时的数据页恢复,内容是记载数据页的物理修改,即编号123数据页的偏移量xxxxxx的数据的k值改为v1。写入方式是循环写,4个log文件构成一个循环,有write pos、checkpoint指针控制写入逻辑。write pos< checkpoint,checkpoint前的修改都是已经将数据页落盘的,之后的是未落盘,write pos追上checkpoint时候会发生强制刷脏页。write pos之后会一直覆盖写。通常redo log是4GB,每个文件1GB大小。

redo log的文件示意图。

为什么有了binlog还要有redo log?

很多人会立即回答,这个日志用途不一样。是的,可能这样问不够清晰。如果限定在crash时的数据恢复领域,就值得思考了。

首先我们都知道WAL机制,如果flush_log_at_trx binlog=1 和 binlog_sync=1,即双1配置。binlog和redo log都是在事务提交前必须得落盘的,其中binlog记录的是所有DDL&DML语句,那么在crash后DB重启,是不是可以重放所有binlog达到数据恢复目的?

答案是不行。从以下几个方面解释:

  • binlog恢复速度比redo慢
  • binlog恢复可能导致数据不准
  • binlog无法保证幂等
  • binlog没有checkpoint

binlog内容记录的是SQL原句,所以在重放时可能会涉及很多数据的更新,自然比redo直接恢复数据页慢很多。

由于记得SQL原句,在update T set time=now() 这种函数时,恢复出来的数据自然是不准确的,违反了事务提交时的数据一致性原则。

最重要的是后面2条原因。1.binlog无法保证幂等,考虑一条SQL。如果数据库多次崩溃,多次重放binlog,那么id=123的行数据的k值就会递增。例如:k初始为0,SQL第一次执行后提交k=1,数据页也落盘了,此时DB crash后恢复重放SQL,k=2这就不对了。

update T set k=k+1 where id = 123

2.binlog没有checkpoint。因为是追加写,没有checkpoint就不知道哪一些脏页已经被落盘刷新。不知道从哪里开始恢复,只能从最开始的binlog开始重放一遍所有的DML语句,这速度和时间消耗着实太大,不适合crash恢复的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值