redoLog和binlog

更新语句的执行流程

一条查询语句的执行流程,会经过连接器、查询缓存、分析器、优化器、执行器等功能模块,最后到达存储引擎;更新语句类似,所不同的是更新的流程中会涉及两个重要的日志模块:redolog和binlog;

mysql> update T set c=c+1 where ID=2;

如上述更新语句,MYSQL会先连接数据库,由于是更新操作,因此会清空表T上所有的查询缓存,进入分析器,经过词法分析和语法分析知道是更新操作,而后优化器会决定是否采用ID索引,执行器负责具体执行;

执行的具体过程

1、执行器请求存储引擎获取ID=2的行数据,存储引擎直接用树搜索该行数据,如果ID=2所在的数据页在内存中就直接返回执行器,否则就从磁盘中读取写入内存并返回;
2、执行器获取到该行数据之后执行+1操作,并将+1后的结果调用存储引擎的接口写入新数据;
3、存储引擎将该行数据更新到内存中,并将更新操作记录到redolog中,此时redolog会处于prepare状态,之后存储引擎会告知执行器执行完毕,可以随时提交事务;
4、执行器生成该操作的binlog日志,写入磁盘;
5、执行器调用存储引擎的提交事务的接口,存储引擎将刚写入的redolog更新为commit状态,更新完成;
具体流程图如下:【其中深色部分表示存储引擎的业务
在这里插入图片描述

重要的日志模块

1、binlog,server层公用的日志模块,主要做的是mysql功能层面上的事情;
2、redolog,引擎层独有的日志模块,主要处理引擎相关的事情;
两者的区别如下:
1、binlog是server层公共的日志模块,主要作用是归档;而redolog是InnoDb引擎独有的,用于实现crash-safe的能力;
2、binlog是逻辑日志,记录的是执行的sql语句或者更新前后的数据行;而redolog是物理日志,记录了在某个数据页中做了哪些修改;
3、binlog是追加写日志,当日志文件写到一定大小之后会切换到下一个,而redolog是基于固定空间大小的日志文件循环写日志;

简述Redolog

MYSQL的每次更新操作都是需要操作磁盘,更新之前也需要从磁盘中读入更新的数据行,因此整个过程IO成本还是比较大的,为了解决这个问题,MYSQL采用了WAL技术(Write Ahread Logging),即先写日志,再写磁盘。
具体的说,InnoDb引擎会把记录更新到redo log中,并更新内存,这个时候更新就完成了,同时,InnoDB引擎会在合适的时机将日志flush到磁盘中,而这个操作往往会在空闲的时间执行;
InnoDB的redolog是固定大小的,比如设置成一组4个文件,每个文件大小在1G,这样redolog总共可以记录4G的记录,从头开始写,当写到末尾就会继续从头开始循环写入;
在这里插入图片描述
如上图所示,writepos是当前写入的位置,边写边往后移,当写到第3个文件之后便向第0个文件开始继续循环写入;
check point是擦除记录的位置,同样也是往后循环推移,擦除记录的同时会将记录更新到数据文件中;
有了redolog,InnoDB就能保证在异常重启恢复的时候,保证之前的数据不会丢失,这就是所谓的crash-safe
其原理,有点类似于店铺掌柜结账的过程,对于赊账的记录会记录到账本上,如果有客户上门结账,掌柜会将结账先记录到白板上,等店铺没什么生意了,或者打烊的时候,店铺掌柜会将白板上的结账和账本上的赊账记录进行逐条结算;
其中,白板就有点类似InnoDB的redolog,账本就是磁盘,由于白板的空间有限,当出现白板不够记录,这个时候掌柜就必须将一些结账记录清除,同时到账本上结算,给新的记录留出空间。

为什么需要设计两个日志模块呢?

原因在于,一开始mysql的存储引擎里并没有Innodb,默认存储引擎是MyISAM,由于MyISAM没有crash-safe的能力,因此binlog日志只能用于归档功能,而InnoDB是另一家公司以插件的形式引入Mysql,由于binlog没有crash-safe的能力,因此InnoDb独自开发了一套redolog用于实现crash-safe能力;

两阶段提交

在这里插入图片描述
基于上述流程分析,redolog 两次,binlog一次,且redolog和binlog相互独立,而binlog写入刚好在这两次的redolog之间,这两次的写入状态不同,这也就保证了一致性;
怎么说呢?

update t set status = 1 where status-0

举一个简单的例子:
如果第一次写入redolog成功之后,写入binlog失败,MYSQL会当做事务失败直接回滚,保证了后续根据redolog和binlog,数据库中的status值仍然为0;
如果第一次写入redolog成功,binlog也写入成功,当第二次写入redolog时候失败了,那数据恢复的过程中,MYSQL判断redolog状态为prepare,且存在对应的binlog记录,则会重放事务提交,数据库中的status值会更新为1;

总结

文章主要介绍MYSQL重要的日志模块,binlog和redolog;
redolog独有的两阶段提交,主要用于保证crash-safe的能力;binlog主要用于归档;
重要的时候可以根据redolog来快速恢复数据,结合binlog可以保证数据库恢复到异常之前的状态;
MYSQL中有两个重要的参数:
(1)Innodb_flush_log_at_trx_commit;每次事务提交都会将redolog写入磁盘;
(2)sync_binlog;每次事务提交之后都会将binlog写入磁盘;
建议都设置成为1,这样才能保证异常重启之后数据不丢失;
最后,MYSQL建议设置定期全量备份,根据数据的重要性,决定是否需要一周一备,还是一日一备;
不管怎样,周期不同,所带来的效益也是不同的:
若采用一日一备,只要当天的全备,加上异常crash之前某段时间的binlog就能快速恢复;
若采用一周一备,假设是每周一备份一次,假设crash当天是周日,就需要周一当天的全备,加上周一到周日该段时间内的binlog日志来恢复;时间成本肯定会比较大;
其次,一周一备份就需要保证一整周的binlog日志完好,否则无法恢复;如果一天一备,只需要保证当天的binlog完整即可。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值