Redo log学习总结

前言

事务

begin;
update 语句 id=8----0
commit
  1. 修改buffer pool里面的页数据—脏页
  2. update语句–>生成一个redo log
  3. redo log 持久化(事务提交的时候)
  4. 修改成功

什么是Redo log

innodb的数据文件是由相等大小页的序列组成,如果我们要编辑它,需要把它加载到内存,在内存中操作它,对于那些在内存中被改变的页,被更新到磁盘之前,是做为脏页标记的,这做为redo log的原始数据,存放在局部作用域的mini transaction缓冲区,执行完mtr_commit会转移到一个全局的redo log的缓冲区,接下来通过各种机制刷新到磁盘,形成redo log文件,默认存放于mysql的数据目录,默认文件个数是2。

与binlog的区别是什么:

  1. 生成时间上:binlog是在sql语句或transaction执行完,但任何相关的locks还未释放或事务还未最终commit前,而redo log是在事物进行中,一直写入重做日志
  2. 存储内容上:binlog记录的是事件,和mysql相关的ddl、dml会记录下来,存储的是逻辑上的数据,而redo log记录了数据文件物理页的变更,如上一篇文章所说的,包括页的原始设置是什么,对他们做了哪些改变,它由文件头、日志快、日志序列号等组成
  3. 一个是针对mysql的事件操作记录器,一个是真对mysql innodb存储引擎实现原子性的保证

为什么引入Redo log

Redo log可以看做是innodb数据最终落到数据文件的中间步骤,那为什么要多处一个步骤?主要出于以下的目的:

  1. 性能考虑:
    为了保证io的性能,系统分配连续的存储空间,已追加的方式写日志,比随机写,性能要好,另外引入redo log buffer,先写buffer,然后批量更新至redolog文件。
  2. 事物的原子性
    innodb是支持事物的,假如只接操作数据文件当操作逻辑进行到一部分时,服务器宕机或者mysql crash,就会出现一个事物的数据部分成功的情况,这是不被允许的,假如引入redo log,可以把这个事物的操作线记录在redo log,当出现宕机或者服务crash时,重启mysql,服务启动会根据checkpoint检查redo log,找到待刷新至数据文件的记录,如果有一个事物内,出现部分更新至数据文件,部分还未更新的数据,执行commit或者rollback,未什么能rollback,因为redo log里会记录页的原始内容
  3. 事物的持久性
    因为redo log文件已经被持久化,所以系统可以根据redo log文件,对数据文件做更新
  • WAL(日志预写)
    称为Write-Ahead-Log,对数据的变更,先写操作日志,然后再更新数据,需要保证在数据更新前,你的操作日志一定要先写到磁盘上,mysql、postgresql、zookeeper对数据的变更都应用了wal
  • Redo log三种不同程度的刷新方式
  1. innodb_flush_log_at_trx_commit = 1
    每次事物提交,执行flush buffer+write+fsync,把脏页数据,刷新至redo log的buffer,并写入redo log,在同步至磁盘,保证落地到redo log文件,mysql默认的刷新方式,最安全的一种方式,即使宕机也不会丢失事物,mysql主库,一般都是该方式

  2. innodb_flush_log_at_trx_commit = 2
    每次事物提交,执行flush buffer+write,刷新脏页数据至redo log buffer,写入redo log文件,crash不丢失事物,宕机则可能丢失,因为它是操作系统延迟写入的

  3. innodb_flush_log_at_trx_commit = 0
    无论事物是否提交,仅仅会把脏页数据发送至redo log buffer,不会触发write操作,留给后台线程每秒一次的write+fsync操作,crash或宕机都有可能丢失事物

引用一个淘宝mysql团队的图片:

在这里插入图片描述

  • 日志刷新测试
    准备工作
use test
create table t_innodb (a int) engine=innodb;
create table t_myisam (a int) engine=myisam;
--存储过程
delimiter //
create procedure insert_testdata(p1 int)
begin
 set @x:=0;
 repeat 
  set @x=@x+1;
  insert into t_myisam values (@x);
  insert into t_innodb values (@x);
  commit;
 until @x>p1 end repeat;
end
  1. innodb_flush_log_at_trx_commit = 1

在这里插入图片描述

插入1000000次过程中,模拟服务crash,直接kill掉mysql,t_myisam-t_innodb=0,注意这里差值为0或者1都是正确的,当0时候,说明crash时候的commit之行了已经,如果为1时,说明当时crash时候,commit未执行,差值永远不会超过1

  1. innodb_flush_log_at_trx_commit = 2
    在这里插入图片描述
    在这里插入图片描述

这里是正常的,如果是服务crash这里的差值应该为1或0,永远不超过1,因为系统没有宕机,文件延迟写入后,结果是和innodb_flush_log_at_trx_commit=1一样的

  1. innodb_flush_log_at_trx_commit = 0

在这里插入图片描述
在这里插入图片描述

这个就是无论事物提交与否都任性的,不写入文件,导致的差异,目测事物成功执行的次数是136505或者136504,那么丢了多少事物呢,136505(136504)-123997的差值

原文链接

https://my.oschina.net/13426421702/blog/809955

其它博客

Redo log https://blog.csdn.net/shayuwei/article/details/90052722
redo和undo日志 https://blog.csdn.net/yu757371316/article/details/81081669
谈谈传说中的redo log是什么?有啥用? https://www.shangmayuan.com/a/380361310a384c10a656597f.html
详细分析MySQL事务日志(redo log和undo log) https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html

视频资料

https://www.bilibili.com/video/BV1xX4y1V7ug?p=25

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值