redo log和bin log 以及MySQL InnoDB内部的XA

本文详细解析了MySQL中Redolog(重做日志)用于数据修改持久化,Undolog(撤销日志)确保事务原子性,以及Binlog(二进制日志)在分布式复制中的作用。理解它们的工作原理有助于提升数据库性能和事务一致性。

知识回顾

1、什么是redo log ?
MySQL 可以分为 连接层、SQL 层、存储层。当sql执行的时候,对数据的修改如果每次都是刷到磁盘上,那么必然会造成大量的随机io,影响效率。所以可以使用redo log 来解决这个问题,即MySQL 对数据的修改只体现在buffer pool 的内存中,然后会在redo log 中记录修改。redo log 还保证了数据的持久性,即修改 的数据一定会最终持久化到磁盘上。redo log 本质上就是固定大小的文件,记录了一些事务的修改操作。注意InnoDB 引擎 会有redolog 好处是可以将多次随机磁盘io 转化为对redo log 的一次顺序io,当buffer pool中的脏页刷盘之后,redolog 中相应的日志也会无意义,即其check point 会推进。带来的影响就是额外的redolog 读写对性能的影响 和数据库刚开始启动时候从redo log恢复数据页面的消耗。

redolog 也不是对于每条日志都进行一次磁盘io,而是先写redolog buffer ,然后每秒刷盘(当然可以通过参数控制 反正频率比较高)
2、什么是undo log?
为了事务持久性的需要,和防止buffer pool 的数据丢失 innoDB 引入了redolog,为了满足事务的原子性引入了unlog。为了满足事务的原子性,在操作数据之前首先将数据备份到undolog 中再操作,所以如果出现了错误或者执行了ROLLBACK ,则可以从undo log中恢复之前的数据。

与redo log不同的是,磁盘上不存在单独的undo log文件,它存放在数据库内部的一个特殊段(segment)中,这称为undo段(undo segment),undo段位于共享表空间内。
innodb的undo log是记录在数据文件(ibd)中的,而且innodb将undo log的内容看作是数据,因此对undo log本身的操作(如向undo log中插入一条undo记录等),都会记录redo log。undo log可以不必立即持久化到磁盘上。即便丢失了,也可以通过redo log将其恢复。因此当插入一条记录时:
1向undo log中插入一条undo log记录。
2向redo log中插入一条”插入undo log记录“的redo log记录。
3插入数据。
4向redo log中插入一条”insert”的redo log记录。

3、 什么是binlog?
binlog 记录了所有更新数据的语句,主要描述了数据的更改。用于Master /salve 数据复制。

侧重-XA 分布式事务

1、分布式事务2PC
xa 有TM 和RM 的概念,TM:全局事务管理器,开始全局事务,提交或者回滚全局事务。RM :资源管理器。可以将TM 理解为协调者 而 RM理解为参与者。

准备阶段:
1、协调者向所有参与者发送准备请求和事务内容,参与者接受到后如果能够执行成功事务则返回yes,如果不能则返回no.
2、协调者收到各参与者的返回信息之后,如果各参与者均返回yes 说明可以提交 否则不能提交 roolback.
提交阶段
1、如果参与者都返回yes那么就会发送提交请求给各参与者发送提交请求,然后等待结果。如果所有参与者都将事务提交成功则此次分布式事务也就提交成功结束。
否则就需要各个参与者利用自己的undo 日志 ROLLBACK。
在这里插入图片描述
MYSQL 中的xa 可以分为外部XA 和内部XA,外部XA 就是分布式事务,而内部XA,主要是保证同一个MySQL Server 下的各个数据库实例的全局事务一致性。同时内部XA 解决了binlog 和redo log 一致性问题。
其prepare 阶段:是redo log 的write / sync
commit 阶段:binlog 的write /sync、写入commit 标志。

所以假如在redo log 写完之后 发生了crash ,此时恢复的时候直接回滚。
如果在未写完binlog 时候发生了 crash ,此时回复的时候也要回滚。
如果在写完binlog 后发生crash 此时需要提交事务。

MySQL 的事务处理流程中,涉及多个日志(如 redo logbin log、undo log)以及数据修改操作,它们的执行顺序工作流程是为了保证事务的 **ACID 特性**(原子性、一致性、隔离性、持久性),同时确保主从复制的一致性崩溃恢复的可靠性。 ### 1. 事务执行流程概述 事务的执行主要包括以下几个关键步骤: - **数据修改(修改缓冲池中的数据页)** - **记录 undo log** - **生成 redo log** - **提交事务(commit)** - **写入 bin log(仅在事务提交时)** - **刷盘操作(根据配置决定何时刷盘)** ### 2. 详细执行顺序与流程 #### 数据修改与 undo log 当执行一个更新语句(如 `UPDATE table SET col = value WHERE id = 1`)时,InnoDB 首先会在缓冲池中对数据页进行修改,并记录 **undo log**,用于支持事务的回滚 MVCC(多版本并发控制)。 - 修改数据页前,会先记录 undo log,以保证事务的原子性[^2]。 #### 生成 redo log 在数据页被修改的同时,InnoDB 会生成 **redo log**,用于在系统崩溃后恢复内存中的数据变更。redo log 是物理日志,记录的是“对数据页的修改”。 - redo log 会在事务执行过程中随时写入,但只有在事务提交时才会被标记为持久化(取决于刷盘策略)[^3]。 #### 两阶段提交(Prepare Commit) 为了保证 **redo log bin log 的一致性**,MySQL 使用了 **两阶段提交机制**(XA 事务)。 1. **Prepare 阶段**: - 将事务的 XID(事务 ID)写入 redo log。 - 将 redo log 刷盘(取决于 `innodb_flush_log_at_trx_commit` 配置)。 - 将事务状态标记为 prepare。 2. **Commit 阶段**: - 将事务的 XID 写入 bin log。 - 将 bin log 刷盘(取决于 `sync_binlog` 配置)。 - 调用引擎的提交接口,将 redo log 的状态标记为 commit。 如果在 Prepare 阶段后崩溃,恢复时会检查 bin log 中是否存在该 XID,若存在则提交事务,否则回滚,确保主从一致性[^4]。 #### 数据刷盘 - **redo log 刷盘**:在 Prepare 阶段完成时刷盘,以确保事务的持久性。 - **bin log 刷盘**:在 Commit 阶段完成时刷盘,确保主从复制的准确性。 - **数据页刷盘**:由后台线程异步完成,不一定在事务提交时立即刷盘。 ### 3. 完整执行顺序总结 1. 修改数据页 2. 记录 undo log 3. 生成 redo log 4. Prepare 阶段(写入 XID 到 redo log,刷盘) 5. 写入 bin log(事务提交时) 6. Commit 阶段(写入 XID 到 bin log,刷盘,标记 redo log 为 commit) 7. 数据页异步刷盘 ### 4. 代码示例:事务提交流程伪代码 ```c start_transaction() { modify_data_in_buffer_pool(); write_undo_log(); generate_redo_log(); } prepare_phase() { write_xid_to_redo_log(); flush_redo_log_to_disk(); set_redo_log_status_to_prepare(); } commit_phase() { write_xid_to_binlog(); flush_binlog_to_disk(); set_redo_log_status_to_commit(); } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值