Mysql binlog redolog与crash-safe

2019-08-06  本文已影响0人  RagingBruce

Part 1 What and Why

什么是redog和binlog?

redolog是对记录修改之后的物理日志,物理日志就是说redolog保存的是某一行数据修改之后的值,比如把id=1这行的某个属性由1改成2,redolog记录的就是这个2.redolog是InnoDB引擎层的。

相比于redolog,binlog是逻辑日志。其中一种形式是记录的原始sql语句,比如update t set c = c +1 where id = 1; binlog是数据库server层的。

为什么需要redolog?

由于更新数据的时候引擎并不是按条更新的,而是以页为最小单位更新。如果没有redolog,每次更新一条数据都要把整页的数据刷新到磁盘。如果更新多条数据,很可能一次就要更新多页,而且这些io是随机io,磁盘i/o就会多且慢。有了redolog,就不需要每次直接按页更新磁盘,而是把更新写到redolog中,然后等空闲时间再把redolog中的更新写入到磁盘。这样做的好处是redolog是顺序写的,而且是按条不是按页写。所以虽然多了一步,实际上是比直接更新快的。

为什么binlog不能做到crash-safe

假如只有binlog,有可能先提交事务再写binlog,有可能事务提交数据更新之后数据库崩了,还没来得及写binlog。我们都知道binlog一般用来做数据库的主从复制或恢复数据库,这样就导致主从数据库不一致或者无法恢复数据库了。同样即使先写binlog再提交事务更新数据库,还是有可能写binlog成功之后数据库崩掉而导致数据库更新失败,这样也会导致主从数据库不一致或者无法恢复数据库。所以只有binlog做不到crash-safe。为了支持crash-safe,需要redolog,而且为了保证逻辑一致,事务提交需要两个阶段:prepare阶段和commit阶段。写redolog并落入磁盘(prepare状态)-->写binlog-->commit。commit的时候是不会落盘的。

那么为什么要在prepare阶段就落盘呢?

如果binlog写成功之后,将redolog置成commit的时候数据库崩了,如果在commit的时候redolog才落盘,由于事务是否成功以binlog为依据,上面的情况下事务是成功的,但是redolog没有写到磁盘,丢了。恢复之后数据库与binlog就不一致了。如果在prepare阶段落盘,上面的情况下redolog已经写入到文件了(在prepare阶段已经写盘了),恢复的时候不会丢数据。

同样的,如果不分两个阶段。假如redolog和binlog独立,那么还是会出现“为什么binlog不能做到crash-safe”里面描述的问题:数据库与binlog不一致。

写的比较粗略,细节很多没写,目的主要是为了解决自己的几个疑问。需要读者有redolog和binlog的基础知识。

上一篇下一篇

猜你喜欢

热点阅读