redo log 叫做重做日志,是用来实现事务的持久性。
该日志有两部分组成:重做日志缓冲(redo log buffer)和重做日志文件(redo log)。
前者在内存中,后者在磁盘中。当事务提交之后会把所有修改信息存到该日志中,用于在刷新脏页到磁盘时,或者发生错误时,进行数据恢复使用。
在银行转账操作中使用事务,从银行账户表中转出2000元到理财账户表中。
数据准备
select version();
8.0.30
create database if not exists db_test default character set utf8mb4 collate utf8mb4_0900_ai_ci;
use db_test;
create table if not exists tb_bank
(
id int primary key auto_increment,
name varchar(20) not null comment '账户名称',
balance int not null comment '账单资金'
) engine = innodb
default charset = utf8mb4
collate = utf8mb4_0900_ai_ci
comment '银行账户表';
create table if not exists tb_finance
(
id int primary key auto_increment,
name varchar(20) not null comment '账户名称',
account int not null comment '账单资金'
) engine = innodb
default charset = utf8mb4
collate = utf8mb4_0900_ai_ci
comment '理财账户表';
insert into tb_bank
values (null, 'Tom', 10000);
insert into tb_finance
values (null, 'Tom', 0);
数据验证
select * from tb_bank;
1,Tom,10000
select * from tb_finance;
1,Tom,0
执行事务操作
start transaction;
select balance from tb_bank where name = 'Tom';
-- 生成重做日志 balance = 8000
update tb_bank set balance = balance - 2000 where name = 'Tom';
-- 生成重做日志 account = 8000
update tb_finance set account = account + 2000 where name = 'Tom';
commit ;
流程

mysql 为了提升性能把每次修改的数据同步到磁盘,而是会先存到 Buffer Pool 中,把这个当作缓存,然后使用后台的线程将缓存刷新到磁盘。
当在执行刷新时,宕机或者断电,可能会丢失部分数据。所以引入 redo log 来记录已成功提交事务的修改信息,并且在事务提交时会把 redo log 持久化到磁盘,系统重启后再读取 redo log 恢复最新数据。
redo log 用于恢复数据,保障已提交事务的持久化特性。
undo log 叫做回滚日志,用户记录数据被修改前的信息,作用包含两个:提供回滚和 MVCC(多版本并发控制)。
与 redo log 相反,undo log 记录被修改前的信息。 undo log 主要记录数据的逻辑变化,可以在发生错误时将之前的记录的逻辑变化进行回滚。