Mysql的各种log(binlog、redo log、undo log)

MySQL常见的三种log:

  • binlog
  • redolog
  • undolog

binlog

什么是binlog

binlog是在mysql的服务层产生的

binlog记录了数据库表结构和表数据变更,它不会记录select(因为这没有对表没有进行变更)

可以简单理解为:存储着每条变更的SQL语句(可能不止SQL,还有XID「事务Id」等等)

Mysql的各种log(binlog、redo log、undo log)_第1张图片

用途

主要有两个作用:复制恢复数据

  • MySQL使用一主多从结构时,从服务器需要与主服务器的数据保持一致,通过binlog来实现的
  • 可以通过binlog对数据进行恢复

redo log

redo log是在innodb即存储引擎层产生的

Mysql的基本存储结构是页(记录都存在页里边),所以MySQL是先把这条记录所在的页找到,然后把该页加载到内存中,将对应记录进行修改

那就可能存在一个问题:如果在内存中把数据改了,还没来得及落磁盘,而此时的数据库挂了怎么办?

Mysql的各种log(binlog、redo log、undo log)_第2张图片
肯定不能每次修改就更新到磁盘,但是不更新到磁盘又怕有数据丢失的风险。InnoDB引入了redolog:内存写完了,会写一份redolog(记载着这次在某个页上做了什么修改)

写redo log的时候,也会有buffer,是先写buffer,再真正落到磁盘中的。至于从buffer什么时候落磁盘,会有配置供我们配置。

写redo log也是需要写磁盘的,但它的好处就是顺序IO(顺序IO比随机IO快非常多)。

当我们修改的时候,写完内存了,但数据还没真正写到磁盘的时候。此时我们的数据库挂了,我们可以根据redo log来对数据进行恢复。因为redo log是顺序IO,所以写入的速度很快,并且redo log记载的是物理变化(xxxx页做了xxx修改),文件的体积很小,恢复速度很快。

binlog和redo log

区别:

存储内容

binlog记载的是update/delete/insert这样的SQL语句,而redo log记载的是物理修改的内容(xxxx页修改了xxx)。

redo log 记录的是数据的物理变化binlog 记录的是数据的逻辑变化

功能

redo log是为持久性、恢复数据用的,而binlog不仅可以用于恢复数据,还用于主从复制。

redo log是一个环形结构,是有限的,数据刷到磁盘后redo log就无效,如果redo log满了,mysql还得停一下来刷新数据到磁盘,也就是刷脏页。

写入细节

redo log是MySQL的InnoDB引擎所产生的。

binlog无论MySQL用什么引擎,都会有的。

InnoDB事务的持久性就是靠redo log来实现的(如果写入内存成功,但数据还没真正刷到磁盘,如果此时的数据库挂了,我们可以靠redo log来恢复内存的数据,这就实现了持久性)

redo log事务开始的时候,就开始记录每次的变更信息,而binlog是在事务提交的时候才记录。

问题出现了:写其中的某一个log,失败了,那会怎么办?现在我们的前提是先写redo log,再写binlog,我们来看看:

  • 如果写redo log失败了,那我们就认为这次事务有问题,回滚,不去写binlog。

  • 如果写redo log成功了,写binlog,写binlog写一半了,但失败了怎么办?我们还是会对这次的事务回滚,将无效的binlog给删除(因为binlog会影响从库的数据,所以需要做删除操作)

  • 如果写redo log和binlog都成功了,那这次算是事务才会真正成功。

简单来说:MySQL需要保证redo log和binlog的数据是一致的,如果不一致,那就乱套了。

  • 如果redo log写失败了,而binlog写成功了。那假设内存的数据还没来得及落磁盘,机器就挂掉了。那主从服务器的数据就不一致了。(从服务器通过binlog得到最新的数据,而主服务器由于redo log没有记载,没法恢复数据)。而且Mysql迅速恢复的时候redo log没有这条信息,而binlog又有,如果用binlog去恢复数据,会让Mysql看起来像是多做了一些事。

  • 如果redo log写成功了,而binlog写失败了。那从服务器就拿不到最新的数据了,而且以后做数据备份的时候也会丢失了这条记录。

MySQL通过两阶段提交来保证redo log和binlog的数据是一致的。

过程:

  • 阶段1:redo log 写盘,处于 prepare 状态

  • 阶段2:binlog 写盘,redo log 处于 commit 状态

undo log

undo log主要有两个作用:回滚多版本控制(MVCC)

在数据修改的时候,不仅记录了redo log,还记录undo log,如果因为某些原因导致事务失败或回滚了,可以用undo log进行回滚(保证了原子性)

undo log主要存储的是逻辑日志,用来回滚的相反操作日志。比如我们要insert一条数据了,那undo log会记录的一条对应的delete日志。我们要update一条记录时,它会记录一条对应相反的update记录。

因为undo log存储着修改之前的数据,相当于一个前版本,MVCC实现的是读写不阻塞,读的时候只要返回前一个版本的数据就行了。

你可能感兴趣的:(mysql,mysql)