后端一个疑问
全部评论

也可以做,但是binlog保存的是全量的数据。他不知道哪些页属于脏页(写入物理页但没写回磁盘),使用binlog恢复我的理解是需要使用所有binlog数据恢复。而redolog记录了哪些页为脏页。重做的时候只需要重做这些数据就行。效率会高很多

binlog是记录的是sql级别的日志,redolog是物理级别的日志,重做肯定是redolog快
评论区还没有说清楚的一点是,mysql 的redo log是一个环形缓存的,大小一般为5g,写满了会从投开始写。而binlog没有上限。
当然数据库并不是一定要求记录逻辑日志binlog,很多分布式数据库已经实现了以物理日志来同步,将物理日志空间不设为环形,进而大大提高性能

一般都是redolog搭配binlog进行恢复的 属于二阶段提交 分成Prepare 阶段,首先数据修改写入缓冲区,生成 redo log 并刷盘,状态标记为 prepare,此时 bin log 还没写入,事务未提交。Commit 阶段:将事务的 SQL 操作写入 bin log 并刷盘。将 redo log 状态更新为 commit,标志事务提交完成 所以在恢复的时候 ,会按顺序扫描 redo log 并检查 binlog如果检查redo log 状态为 commit 就直接不用管binlog了因为事务肯定是提交了直接重做数据业 如果 redo log 状态为 prepare,那么就要再去检查binlog 如果binlog 完整,那么就提交事务,重做数据 如果binlog不完整 就回滚事务
首先,需要明确 MySQL 中这两种 log 存放的是什么数据。
binlog 是 MySQL 自己的日志,它里面存放的是二进制格式的 SQL 语句 或 变化的每行 SQL 信息。(具体要看 binlog_format 是 STATEMENT 还是 ROW)为了简化讨论,就把它当作存放了一堆 SQL 的二进制文件。
redo log 是 InnoDB 的日志,InnoDB 是 MySQL 的一种可选引擎。redo log 里面存放的是对 InnoDB 数据页面的「修改动作」,可以抽象成把某个字节从 X 改成 Y。由于它只记录操作,所以 redo log 并不清楚这些操作在逻辑上对应什么。
(数据页面也简单解释下,可以想象成把表里的数据,一行接一行的排列到一个大的文件中。修改数据页面的动作,实际上就是在修改行内的数据。)
基本概念对齐以后,我们来考虑没有 redo log 会怎么样。我们要知道 binlog 和 磁盘上的数据页 从物理上没办法保证同时写入完成,总归会有先后。那么我们写入 binlog 后,数据页面刷到一半,机器断电了,我们如何把数据页从茫茫字节中,恢复到之前的内容呢?(这里还涉及一个 doublewrite buffer 的概念,但为了聚焦问题,先假设一次性刷写能完整刷写一个页面)
可以简单认为,MySQL 决定一个事务是否成功提交,取决于 binlog。假设 binlog 是完整的,存储引擎无论如何都得把这条 binlog 对应的记录还原回来,否则事务就丢失了。同时 MySQL 主备复制也是依赖 binlog,也就是 binlog 具有 “一票否决权”。而 redo log 是 InnoDB 指导自己如何恢复数据的。
从我的表述来看,redo log 和 binlog 必须保证一致。要么都有,要么都没有。这点从物理上无法保证,但是从逻辑上可以。redo log 先写入本次操作,并记录 “type” 为 prepare;这时写入 binlog,再写入一条 redo log commit 记录。
假设1:只有 redo log prepare,没有 binlog。说明事务没有提交,我需要根据 redo log prepare 的操作指导,保证数据页的正确性。
假设2:有 binlog,没有 redo log commit。说明事务是正确提交的,只是 redo commit 没来得及写入,我需要根据 redo log prepare 的操作指导,进行页面数据恢复。
其实,当你觉得一个东西不需要的时候,想象一下把它去掉,这个系统是否可以保证正确。
binlog是一条一条的增删改的记录,redolog记录的是物理页面的修改。如果使用binlog的话,需要一条一条执行sql,redolog的话基于物理页要快一些。你也可以拓展一下,就好像redis中两个持久化机制,一个rdb一个aof,rdb一般记录的是全量的物理数据,aof记录的一条一条的增删改,redis里面使用rdb恢复或者是备份也是很快的。
binlog不能给脏页刷盘
binlog并不是一个原子的操作,一条binlog可能对应多条redo log,如果只使用binlog,那么需要先落盘binlog,再落盘数据,如果此时数据只落盘了一部分就挂了,恢复时无法通过binlog进行重做。
但是主从不也是用的binlog吗
用binlog也行,满足两个前提,1,MySQL一开始使用的时候就开启binlog,且中途无异常,2,先把数据库中的数据清空
个人理解,binlog慢
redo log:解决事务持久性 & crash recovery(快,物理级别)。
binlog:用于主从复制、备份恢复(逻辑级别,跨存储引擎)。
再了解一下两阶段提交你就懂了
相关推荐

点赞 评论 收藏
分享
点赞 评论 收藏
分享

点赞 评论 收藏
分享