mysql redolog 和binlog的理解

概念

1,redolog 是记录页修改的日志,比如 再更新一个字段的操作中 就会记录哪个页 对哪个字段的修改 属于物理日志

redolog 是innodb引擎特有的

2,binlog 记录了更新的语句  是逻辑日志  是server层实现的

分析

一条更新sql语句的执行过程

盗用 丁奇大神的一张图

mysql redolog 和binlog的理解

1. 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁 盘读入内存,然后再返回。

2. 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到 新的一行数据,再调用引擎接口写入这行新数据。

3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。

4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。

5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状 态,更新完成。

崩溃与恢复

如上图如果在时刻A的时候 也就是写入redolog 处于prepare阶段 还未写入binlog的时候 崩溃了  此时redolog还没提交binlog也还没写 ,恢复的时候 就直接回滚了 

如果时刻B的时候 binlog已经写入 redolog 在提交的时候 发生崩溃了 那恢复的时候 怎么处理呢

先看下崩溃恢复时的判断规则

规则1:redolog里面的事务是完整的 也就是有了commit标识,则直接提交

规则2:redolog 里面的事务是prepare状态,那么再判断对应的binlog是否完整存在 如果完整存在 提交事务,否则回滚

所以时刻B 的状态应该是redolog是prepare状态  binlog完整 那么崩溃恢复时事务会被提交

redolog 和 binlog关联

上面有个疑问就是崩溃恢复时 先看redolog的状态 如果redolog为prepare状态 那么就会找与之相对应的binlog 二者之间是通过什么关联的呢

redolog和binlog 有一个共同的数据字段 叫 XID崩溃恢复的时候 如果redolog为parepare状态则拿着XID去binlog找对应的事务

数据落盘

如上面的sql执行流程可以看到 数据修改先在内存中修改,内存中的数据页和磁盘数据页就不一样了 就是脏页 ,将脏页刷新到磁盘中 这就是刷脏,这个过程与redolog没有关系

因为redolog并没有记录数据页的完整数据,所以没有能力自己去更新磁盘数据页

在崩溃恢复的场景中,innodb如果判断一个数据页可能在崩溃恢复的时候丢失了更新,就会把他读到内存,然后让redolog 更新内存内容,更新完成后 内存页变成了脏页,然后就等着被刷到磁盘中

redo log buffer

 

在一个事务中 可能有多个插入操作 日志要写入多次

beging

insert into t1..

insert into t2...

插入的过程中,生成的日志都要先保存起来,等到commit的时候才写到redolog中

所以redo log buffer 就是一块内存  第一个插入后 内存被修改 redo log buffer里也写入了日志

但是真正把日志写到redo log 文件中的是 执行commit操作时做的