mysql+redo的两个阶段_什么是redo日志的“两阶段提交”

本文介绍了MySQL在更新数据时的内部流程,特别是RedoLog和binlog的两阶段提交机制。在MySQL中,为了确保数据一致性,先写RedoLog再写binlog,避免因异常重启导致数据不一致。崩溃恢复时,MySQL会根据RedoLog和binlog的状态来决定是否提交事务,确保数据的一致性和完整性。这一机制对于数据库的crash-safe能力至关重要。
摘要由CSDN通过智能技术生成

MySQL的崩溃恢复crash_safe能力依赖于Redo Log事务日志。当MySQL更改数据的时候,它的设计思想是先对内存中的数据进行修改,并且写Redo Log,即更改数据,总是遵循WAL日志先行机制。

那为啥redo日志是两阶段提交呢? 这是需要和它处在的环境条件有关系的。那首先先看下read log是如何进行数据修改操作的。

当MySQL更新数据的时候,其内部流程是怎么实现的呢?

假设我要执行一条SQL:update T set name = 'winner' where ID=2,那么内部执行流程为:

1、优化器找存储引擎取出ID=2这一行,如果ID=2这一行记录所在的数据页本身就在内存当中,那么就直接返回给执行器;否则需要从磁盘读取到内存当中,然后再返回给优化器;

2、优化器拿到行数据之后,会对内存中的数据页进行修改,同时将这个更新操作记录到Redo Log。此时Redo Log处于 perpare 状态,然后告知执行器已经完成了,可以随时提交事务;

3、接下来执行器会生成这个更新操作的binlog;

4、执行器调用存储引擎的提交事务的接口,将刚刚写入的Redo Log改成commit状态;

为什么是需要两阶段呢?

这里它的2阶段是对应于不同类型的日志,所以两阶段为的就是让这个2个不同的日志做好处理与准备。

1、假设是先写Redo Log,后写binlog。如果这个时候MySQL发生了进程的异常重启,由于Redo Log已经写完,MySQL崩溃之后通过crash_safe能力,能够把数据恢复回来。但是由于binlog还没写完就crash了,所以binlog里面并没有记录该SQL语句,所以使用binlog回档数据的时候,恢复出来的数据其实是少了一次更新操作的,这样就造成了灾难恢复出来的库和原库数据不一致;

2、假设是先写binlog,后写Redo Log。Binlog写完之后发生了crash,由于Redo Log还没有写,崩溃恢复之后这个事务的更新是无效的。但是binlog里面记录了这条更新的语句,所以使用binlog回档的时候就多了一条事务的更新。造成回档出来的数据和原库的数据不一致。

那么两阶段提交就是:

1、prepare阶段,写redo log;

2、commit阶段,写binlog并且将redo log的状态改成commit状态;

mysql发生崩溃恢复的过程中,会根据redo log日志,结合 binlog 记录来做事务回滚:

1、如果redo log 和 binlog都存在,逻辑上一致,那么提交事务;

2、如果redo log存在而binlog不存在,逻辑上不一致,那么回滚事务;

最后大家可发现,这里的两阶段提交,实际是存在与redo log与binlog。所以当未开启binlog,那就是提交事务直接写到redo log里面。这也就是redo log事务两阶段提交,看场景区分的原因。

后面将不断的分享技术,同时也欢迎大家关注公众号,获取更多技术好文。听说还可以获取进阶相关的视频资料额。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值