MySQL日志---redo log和binlog

MySQL更新操作

MySQL查询操作

MySQL的更新操作和查询操作大体上一样,都需要经过连接器、分析器、优化器和执行器。有区别的是,在进行更新操作的时候,会有两个重要的日志板块-----redo logbinlog

redo log

redo log通常将其翻译成重做日志(英文中的前缀re表示重复的意思),作为InnoDB特有的日志,它的作用是当有一条记录需要更新的时候,InnoDB引擎会先把记录写到redo log中,同时并更新内存,之后当系统空闲时会把操作记录更新到磁盘里。它减少了执行更新操作的同时将记录写入磁盘的IO压力。

MySQL的redo log的大小是固定的,我们可以根据项目的需求进行大小的调整。redo log的写入是循环的,当写满之后,会重新进行从头部进行写入。

在这里插入图片描述
假设我们有四个redo log文件,write pos是当前记录的位置,而checkpoint是将要擦除的位置,当ib_logfile_3写满之后,会从ib_logfile_0开始记录。当两者相遇时,表示已经写满了,此时checkpoint会擦除一些记录,腾出空间让write pos继续记录。

redo log提供了一种crash safe的能力,即使数据库发生异常重启,InnoDB引擎之前提交的记录都不会丢失。

binlog

binlog通常将其翻译成归档日志(有时也翻译成二进制日志,英文中的前缀bi表示双的意思,binary二进制),与redo log不同的是binlog是MySQL所有的引擎都可以使用的日志,并非InnoDB独有。binlog是逻辑日志,记录的是这个语句的原始逻辑,同时它的记录方式不是循环记录,而是追加写入。

对于update操作,MySQL使用了两阶段提交,目的是为了确保redo log和binlog的逻辑一致性。

1.执行器寻找SQL语句的目标行,如果在内存中就取出,不在的话去磁盘中读入内存,返回给执行器。
2.执行SQL,调用引擎写入数据。
3.引擎将新数据更新到内存中,同时将这个更新操作记录到redo log里面,此时redo log处于prepare状态。同时告知执行器执行完成了,随时可以提交事务。
4.执行器生成这个操作的binlog,并把binlog写入磁盘。
5.执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log改成提交(commit)状态,更新完成。

假设没有使用两阶段提交:

  • 先写redo log 后写binlog:
    当先写完redo log的时候,此时的binlog还没有写完,如果发生故障重启,因为redo log可以恢复,所以数据仍然可以保持完整,但是binlog没有记录下来,当我们备份日志使用binlog恢复数据库的时候,会导致数据缺失。

  • 先写binlog 后写redo log:
    当先写完binlog的时候,此时的redo log还没有写,如果发生故障重启,恢复后会导致binlog有一条记录,而redo log没有,平白无故的多出了一条事务,导致与原库的数据不一致。

猜你喜欢

转载自blog.csdn.net/MAKEJAVAMAN/article/details/118342518