redo log与bin log的个人理解

MySQL数据库的更新流程涉及两个重要的日志模块:redo log与bin log,本文记录一下在学习丁奇大佬的《MySQL实战45讲》过程中我个人的一些理解,如有不对的地方,欢迎指正。

redo log
  • 特点:InnoDB引擎所特有的;是物理日志,记录的是数据“做了什么改动”;redo log循环写,空间固定,会用完。

  • 作用:用于保证数据库发生异常重启恢复数据,之前提交的记录都不会丢失,也就是 crash-safe

  • 理解:数据库更新的部分数据可以暂时保存在内存中,并不是立马写到磁盘中,这样可以减少读写磁盘的次数。但是保存在内存中的数据可能会因为数据库出现异常重启的情况而导致数据丢失,无法从磁盘中的数据恢复最新的数据。有了redo log之后可以解决这个问题,每次更新完数据之前,会在redo log文件中记录数据的变更操作,这样在数据库异常重启之后,会根据磁盘中的数据以及redo log,恢复最新的数据。

bin log
  • 特点:MySQL server层实现的日志,所有存储引擎插件都可以使用;是逻辑日志,记录的是这个语句的原始逻辑(有两种模式,statement格式记录sql语句,row格式会记录行的内容,记两条,更新前与更新后都有);bin log可以追加写,文件写到一定大小会写到下一个文件,不会覆盖以前的日志。
  • 作用:将数据库rollback至某个操作或者某个时间点之前的状态,或者用于备份数据。
  • 理解:无法通过redo log来实现这个rollback操作,因为redo log记录的是内存数据与磁盘数据的变化,就算要通过redo log来rollback,那也只能将最新的数据库回滚到内存中某个时间点的状态,而无法回滚到磁盘中数据的某个时间点。但是通过bin log可以实现这种回滚需求,假设需要回滚至某个删表操作之前的状态,只需要从删除操作之前最近的一个数据备份开始,重新执行bin log中从数据备份开始至删除操作之前的bin log即可。

通过对redo log与bin log的介绍与理解,可知二者作用不同,需同时存在才能实现数据库的某些可用性与可靠性。但是二者之间必须按照某个特定的逻辑顺序来处理才能处理一些出现错误的场景,也就是redo log的两阶段提交,先执行写redo log的prepare阶段,然后执行写bin log,最后执行写redo log的commit阶段,如果中间有某个阶段出错,都会让redo log、bin log回滚。