查询程序崩溃⽇志_MySQL的⽇志-redolog
关注我《程序猿集锦》,获取更多分享。
前⾔
什么是redolog
relaylog的作⽤
物理⽇志VS逻辑⽇志
redolog的组成
redolog的两阶段提交
reldolog⽇志的刷盘
redolog对事物的⽀持
redolog和binlog的区别
redolog其他的⼏个参数
最后
前⾔
前⾯的⽂章中,我们依次介绍了MySQL的slow query log、binlog、relaylog,如果对这三种log仍然有疑问的话,可以向前翻⼀翻⽂章查看。今天我们来聊⼀聊MySQL中的另外⼀个重要的⽇志,它就是redolog。
什么是redolog
redolog,我们经常翻译为重做⽇志。
redolog是InnoDB存储引擎所特有的⼀种⽇志,其他存储引擎没有这个⽇志功能,例如像之前我们⽤过的MyISAM存储引擎就没有这种redolog的功能。我们知道MySQL从宏观上看,可以分为两次:server服务层和store engine存储引擎层。⽽我们的redolog就是属于存储引擎层特有的⽇志。像binlog、relaylog他们是属于服务层⽇志,所有的存储引擎都会⽣成这种⽇志,并且这种⽇志是先于redolog之前写的,写成功binlog之后才会写redolog。
relaylog的作⽤
redolog是⽤来做崩溃恢复使⽤的,这种崩溃恢复不需要我们⼈为的参与,MySQL⾃⼰内部⾃⼰实现了这种崩溃恢复的功能,我们只管享受这种功能给我们带来的服务即可,这种服务给我们的感受就是:MySQL数据库异常宕机的时候,重启服务之后,数据库中之前提交的记录都不会丢失数据仍然可以正常恢复,不管这种提交的记录是否已经更到具体的表所对应的磁盘page也中。
那么MySQL内部在实现崩溃恢复的功能时,到底是如何实现的呢? 举例来说,当有⼀条记录需要更新的时候,InnoDB 引擎就会先把记录写到redo log⾥⾯(redolog⽇志是循环追加写的,属于顺序IO,记录的速度在某些程度上可以和内存相媲美),并更新内存,这个时候更新就算完成了。MySQL在崩溃恢复的时候,会从记下来的redolog中到已经提交的更改内容,所以不会担⼼MySQL异常重启后,数据的丢失。
InnoDB 引擎会在适当的时候,将这redolog中记录的操作更新到表中数据对应的page页所在的物理磁盘上,⽽这个更新往往是在MySQL 服务⽐较空闲的时候去刷新到磁盘,此时才是真正的把更新的数据内容刷新到对应的page页中。⽽这个更新redolog⽇志中的内容到真正的表数据对应的page页的刷盘操作通常⽐费时的,需要从磁盘中到对应的page页,还涉及到分页或合并的各种操作,属于随机IO写⼊性能太差,所以MySQL没有在执⾏更新操作的时候,并没有直接去更新真正的数据页中的内容,⽽只是更新了缓存和记录的redolog⽇志。先写⽇志,再写磁盘,这就是很多软件在提⾼写的性能的时候所使⽤的WAL(write ahead logging)预写⽇志的功能。
MySQL的这种崩溃恢复的功能,这就是我们经常所说的crash-safe,⽽实现这个crash-safe功能的主要组件就是redolog。因为只有innodb存储引擎才有这个特有的⽇志,所有只有innodb才⽀持这种崩溃恢复数据不丢失的特性,这也是为什么innodb存储引擎替代myiasm存储引擎成为主流默认的存储引擎的原因之⼀。
在最早的时候MySQL⾥并没有InnoDB引擎。MySQL⾃带的引擎是MyISAM,但是MyISAM没有crash-safe的能⼒,binlog⽇志只能⽤于归档。⽽InnoDB是另⼀个公司以插件形式引⼊MySQL的,既然只依靠binlog是没有crash-safe能⼒的,所以InnoDB使⽤另外⼀套⽇志系统,也就是redo log来实现crash-safe能⼒。这就是为什么会有relaylog⽇志产⽣的原因。
redolog从另外⼀个维度上来讲,它属于⼀种物理⽇志。
那么什么是物理⽇志呢?物理⽇志记录的是每⼀个page页中具体存储的值是多少,在这个数据页上做了什么修改。与物理⽇志对应的是逻
辑⽇志,逻辑⽇志是记录的每⼀个page页⾯中具体数据是怎么变动的,它会记录⼀个变动的过程,⽐如把ID=3的⾏的age字段改为``30。像undolog、binlog、relaylog`这些⽇志,它们就属于逻辑⽇志,记录的是数据变化的⼀个过程、或SQL语句的逻辑。这样可能⽐较抽
象,不容易理解,我们下⾯举例说明⼀下。
例如我们把⼀个page页总的⼀个数据从1改为2,再从2改为3,再从3改为4,再从4改为5。这是这个数据在page页中变换的过程。在物理⽇志中,它只会记录最后的⼀个值5,表⽰这个page页中的数据的值为5。⽽逻辑⽇志会记录1->2,2->3,3->4,4->5这个数据变化的过程。
redolog的组成
只要是使⽤的innodb存储引擎,那么redolog就⼀定是存在的。它们在磁盘上会落实成固定个数固定⼤⼩的⽇志⽂件。⼀般有2个或4个,
这可以在初始化MySQL实例的时候,可以进⾏配置。如下是我⾃⼰的⼀个MySQL实例的redolog配置,配置了2个redolog⽇志⽂件:
root@test:/var/lib/mysql# pwd/var/lib/mysqlroot@test:/var/lib/mysql# ls -lstr ib_logfile*49152 -rw-r----- 1 mysql mysql 50331648 Dec 28 15:45 ib_logfile1491
决定redolog⽇志⽂件的个数的参数是innodb_log_files_in_group,⽇志⽂件的个数建议设置为3或4。决定每⼀个⽇志⽂件⼤⼩的值为innodb_log_file_size,单个⽇志⽂件最⼤值建议设置为1GB,如下是查看我⾃⼰的⼀个MySQL⽰例的redolog的参数配置信息:
mysql> show variables like 'innodb_log_files_in_group';+---------------------------+-------+| Variable_nam
e            | Value |+---------------------------+-------+| inn 注意:如果要修改这个参数的值,需要停⽌MySQL服务才可以。⼀般在初始化完成之后,不建议修改这个值的⼤⼩。
redo log是循环写的,空间固定会⽤完。它⼀般是由2个或4个⽇志⽂件组成,当写完1个后,会写第2个,当第2个页写完后,会再去写第1个,如此往复循环,当然在写覆盖写第1个⽂件之前,需要把⾥⾯的⽇志内容,刷新到磁盘,然后再去覆盖写。binlog是可以追加写⼊的。"追加写"是指binlog⽂件写到⼀定⼤⼩后会切换到下⼀个,并不会覆盖以前的⽇志。
redolog循环写的⽅式向下⾯这个图⽚所⽰,write pos 到 check point 之间的部分是 redo log 空着的部分,⽤于记录新的记录;check point 到 write pos 之间是 redo log 待刷盘的数据页更改记录。当 write pos追上check point 时,会先推动 check point 向前移动,空
出位置再记录新的⽇志。启动 innodb 的时候,不管上次是正常关闭还是异常关闭,总是会进⾏恢复操作。因为 redo log记录的是数据页
的物理变化,因此恢复的时候速度⽐逻辑⽇志(如 binlog )要快很多。
redo log 循环覆盖写
redolog的两阶段提交
什么是redolog的两阶段提交呢?就是在写redolog⽇志的时候,并不是直接把redolog标记为完成状态。⽽是中间会有⼀个prepare状态。为了更好理解这个概念,这⾥我们参考下⾯这个SQL语句执⾏流程图来分析⼀些这个两阶段提交的含义。
从图中,我们可以看出,⼀条更新语句的⼤致执⾏流程是这样的:
MySQL架构和SQL语句执⾏过程
1. server服务层的执⾏器,调⽤存储引擎层的API接⼝,去查询数据。
2. innodb存储引擎层查询buffer pool缓存中的数据。
3. 如果查询缓存中包含待查询的数据,则直接返回给server服务层的执⾏器。
4. 如果缓存中没有结果则从磁盘中去读取数据,读取数据后,再返回给server服务层,同时把查询到的数据更新到buffer pool中的数据
内容。
5. server层的执⾏器收到查询后的数据后,执⾏更新操作。
6. server层调⽤innodb存储引擎层的API接⼝更新数据。
7. innodb存储引擎层更新数据到change buffer缓存池中。
8. innddb存储引擎层记录redolog,并把其状态设置为prepare状态。
9. innodb存储引擎层通知server的执⾏器,change buffer已经更新,redolog已经进⼊prepare待提交的就绪状态,可以记录binlog
10. server层的执⾏器记录binlog到binlog的缓冲池中。(这⾥缓冲池中的⽇志何时刷盘就是通过参数sync_binlog来控制的,下⾯会详细
介绍。)
11. server层的执⾏器在记录完binlog之后,通知innodb存储引擎层,binlog已经记录完成。
12. innodb存储引擎层收到server记录完binlog的通知后,更新redolog buffer中的redolog为commit状态。(此时redolog buffer中的
⽇志何时刷盘就是通过参数innodb_flush_log_at_trx_commit来控制的,下⾯会详细介绍。)
⾄此,整个更新语句才真正的执⾏完成。通过上⾯的过程可以看出,在记录redolog的时候,有两个过程⼀个是记录redolog⽇志,把它的状态标记为prepare待提交状态,然后等待server层的binlog⽇志记录完成后,才会把redolog的⽇志更新为commit状态。这个过程就是redolog的两阶段提交操作。我们把上⾯的图简化为如下的⼀个图,你更能看明⽩:
redo log的两阶段提交
思考问题:为什么redolog要两阶段提交?
redolog的两阶段提交是实现innodb存储引擎crash-safe功能核⼼。它的重要性,我们可以使⽤反正法来解读。试想⼀下:如果redolog在记录的时候不是两阶段提交。那么会有什么样的后果呢?只能有以下2种情况:
1. 先写redolog,在写binlog:在⼀个更新操作的提交后,如果在redolog写成功之后,还没有来得及写binlog,此时发⽣了异常重启。
由于redolog已经记录成功,所以在异常重启之后,MySQL可以根据redolog中的内容恢复到异常重启之前数据更新后的结果,但是由于binlog没有记录这个更新操作。如果⽇后你拿着这个binlog还原⼀个新库的时候,被还原的数据库中的数据就不会有这个更新操作。此时的新库和原库数据是不⼀致的。
mysql下载哪个盘
2. 先写binlog,在写redolog:在⼀个更新操作的提交后,如果在记录完成binlog之后,还没有来记得写redolog,此时发⽣了异常重
启。由于binlog已经记录了修改操作,所以⽇后在使⽤这个binlog还原新库的时候,被还原的库中会包含这个更新操作,但是由于redolog没有被记录,数据库在异常重启后,并不能恢复到这个更新操作之
后的数据内容。此时被还原的新库和原库中的数据也是不⼀

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。