当前位置: 首页 > 科技观察

为MySQL写操作保驾护航的三兄弟!

时间:2023-03-12 23:04:49 科技观察

本期文章主要是写操作过程中涉及的三个日志文件。看完前面几期,大家可能已经或多或少有所了解(或者从其他地方了解到)。比如整个写操作过程中用到的两阶段提交,或者操作过程中涉及到的日志文件,但总体来说不是很系统,更谈不上全面。今天我们就来认识一下这三兄弟。-思维导图-两阶段提交这个词你应该听过很多次了,所以在这里介绍一下这位老朋友。所谓两阶段提交,字面意思就是应该分两步进行约束。事实上它是。这两个步骤中的主角就是我们今天要讲的两个重要角色:binlog和redolog。说到两阶段提交,就绕不开SQL语句的执行过程。没办法,虽然提过很多次了,但还是得重新拉出来。只是这次的侧重点会和之前的有些不同。具体操作过程如下:当执行某个写操作的SQL时,引擎将一行数据更新到内存中,并在redolog中记录对应的操作,然后进入prepare状态。并将完成信息告知执行者。执行器生成对应操作的binlog,并将binlog写入磁盘。然后调用引擎的commit事务接口,将redolog的状态改为commit,操作完成。好了,既然知道了两阶段提交,那我们就来看看这些日志文件的真面目吧。重做日志(redolog)是重做日志在存储引擎层最先出现的,用来记录“数据页发生了哪些变化”的物理日志文件。WAL技术一提到redolog,就一定不能绕过WAL技术。全称是Write-AheadLogging。即在同步磁盘之前先写入日志,然后系统会按照一定的策略将日志中的记录同步到磁盘中。存在的必要性从上面的两阶段提交流程,我们可以看出WAL技术的使用场景。不知道大家有没有疑惑,为什么中间要写redolog,不可以直接把更新结果同步到磁盘吗?傻孩子,同步到磁盘就是每次写操作都要产生一次随机的磁盘写操作,而且速度极高。多么慢。如果你聪明一点,你可能会说,我是不是可以在一定时间后从内存同步到磁盘呢?这不可能吗?来来来,我先给大家脑补一下,你想想看,我的服务重启了,这些数据还在吗?内存是易失性的,不知道有什么异常情况,数据就会丢失。所以这个时候就需要一个持久化的中间文件来起到“缓冲”的作用,写入速度也不慢。那么redolog就应运而生了。虽然也是存储在磁盘上,但是不影响顺序写入的速度(迷茫的同学可以理解磁盘随机读写和顺序读写的区别)。当然,除了“延迟”同步磁盘文件的作用外,重做日志还可以用来在数据库服务器宕机时恢复数据。写作时机说到写作时机,你是不是比较迷茫?更新内存后写重做日志文件不难吗?答案确实不是,因为中间有一个redologbuffer(在内存中)。Mysql每执行一条语句,都会先将记录写入redologbuffer,然后在后续执行commit操作的某个时刻写入redolog文件(在磁盘上)。值得注意的是,redologbuffer中的数据是在执行commit操作时写入redolog文件的。至于写的时机,是由以下几个参数控制的:(图片来自网络)写法知道了写的时机,这里简单介绍一下写法。在Innodb中,redolog的大小是固定的,所以只能循环写入。如果我目前有4个文件,从第一个文件开始写,直到最后一个文件写满,然后回到开头把数据同步到文件,擦掉再继续写。图中的writepos表示当前记录的位置,随着写入的进行逐渐后移。当写入文件ib_logfile_3时,整个重做日志被填满。此时更新操作将被阻塞。系统根据检查点标记擦除一些记录(当然前提是这些记录同步到磁盘)。总的来说,redolog的写入方式是一个不断写入,写满后擦除,再写入的过程。二进制日志(binlog)说完重做日志,我们再来看看另一个位于服务层的二进制日志文件binlog。这位大哥的作用就是存放逻辑日志。所谓逻辑日志,是指修改了什么,它就会被记录进去。比如:更新id=1的字段。当然,除了记录操作过程,它还有支持master-slave的能力同步和数据异常恢复。写模式binlog中有三种写模式。下面来看看区别和对应的优缺点:(图片来源于网络)写法和redolog循环写法不同,binlog是追加的写法,当一个文件写到某个文件时大小,它会切换到另一个。与redolog的关联在上面的两阶段提交中,我们提到了写入binlog后,会调用引擎的commit事务接口,将redolog的状态改为commit。那么它是如何找到对应的记录的呢,或者说,这两者有什么关系呢?答案是通过一个公共字段XID,不仅在事务提交的时候,遇到崩溃恢复的时候。preparewithoutcommitredolog,也可以使用XID来查找对应的事务。回顾写入过程此时,我们需要回顾一下写入过程的运行。以更新某个字段为例:回滚日志(undolog)说到这里,你可能会一头雾水。整篇文章都没有undolog的影子。你这个没心没肺的人!别着急,它来了!根据字面意思,你应该能猜到它是做什么用的。回滚,就是给你一个后悔的机会。修改数据时,同时记录undolog,即同时记录相反操作的逻辑日志。可以理解为,操作update时,写入对应的update记录,操作delete时,写入对应的insert记录。当事务回滚时。从undolog中读取相应的逻辑记录后,即可进行回滚操作。两阶段提交总结在两阶段提交过程中,在更新内存的同时将相应的操作记录在redolog中,并在事务提交前将生成的binlog写入磁盘。redologredolog是位于存储引擎层的物理日志,用于记录“数据页发生了哪些变化”的物理日志文件。使用循环写入的方式记录数据修改后的外观。它还提供数据恢复功能。二进制日志binlog是位于服务层的逻辑日志,用于记录“数据发生了哪些变化”的日志文件。与重做日志不同,附加写入总是可以执行的。同时还提供了主从同步和异常数据恢复的能力。回滚日志当数据被修改时,同时记录undolog,可以保证事务回滚时的数据恢复。