• mysql详解之redolog的关键——幂等性


    前言

    本篇博客的前提是默认读者已经对mysql-innodb内部原理及各种概念有了比较全面的认识。过了是什么阶段,而在为什么阶段的一些深入思考(关于innoDB的基础原理概念,请期待下一篇博客)。

    问题

    说到redo log,我们都会说它是物理日志(和binlog的逻辑日志做对比)。但没人解释过:为什么要用物理日志。换个马甲,显得高级?

    思考

    很多文章在讲redo log时,好像有意无意的都在强调:redo log写日志时,顺序io带来的或者能保住更多数据。这两点真的是redo log主要追求的东西吗?

    想一个问题:缓冲池是不是就已经最大限度的保证了mysql的处理速度?

    第二个问题:当出现掉电/宕机等问题时。1.保住更多数据。 2. 保障写入数据库表不要出现“写一半”的情况。哪个更重要?

    在我看来这就好像在问:蒸了一锅饭,是撒掉一碗饭严重呢,还是混入一颗老鼠屎严重。
    这一秒断电和下一秒断电又什么本质的区别呢,但如果库里出现了不完整的数据那就糟心了。

    所以:为解决事务而产生的innoDB,主要关注点在于:数据完整性

    log可校验自身完整性

    因为innoDB要支持事务(innodb之前的myISAm不支持事务,就不用考虑这些),而事务的两个特性:原子性(A),持久性(D)。只有缓存无法满足。

    要解决这两个问题,方案就是用日志数据库表文件没法知道自己是否完整。同步记录日志可以通过对每一个事务加标记,来判断自身的完整性(整个数据库就是由一个个完整的事务组成的)。当把日志完整的写到磁盘的那一刻,理论上就已经满足了事务的原子性和持久性。

    问:binlog不也是日志吗,是不是binlog也可以实现事务完整性

    答:是的,但比较麻烦。如果出现数据不一致,需要拿定期备份的完整数据库表文件 + binlog 就可以实现数据的事务的完整。

    关于“binlog可以校验事务完整性”,可以参考 innoDB为了redo log和binlog 的一致,而引入的2pc机制。

    2pc本身是不具备理论上的一致性。虽然innodb在恢复数据时应用了2pc机制,但在最后增加一步:当redo log的事务状态是未完成时,去判断一下binlog的完整性,如果binlog是完整的,就把redo log的事务状态改为已完成。这样就弥补了2pc的逻辑缺陷。同时也印证了binlog确实可以校验自身事务的完整性。

    所以:log可以成为数据库表文件修复的可靠依据。

    log先行

    log的完整性有保证了,还得让log先写(既然有了可靠的领头大哥,小弟就得跟在大哥后面,不能走在前面自作主张)。否则如果数据库表文件的数据比log写的快,突然断电,数据库表文件里写了一些不完整数据,但log文件里还没写完,log就没办法去剔除多余数据了。这就是所谓的WAL(Write-Ahead Logging),日志预写机制。
    所以:WAL不是为了让日志多保留数据,而是在防止数据库表文件多写数据(还是事务数据完整性),以达到:当出现问题时,数据库表文件永远比log慢半拍,最后以log为准,去修正数据

    正题

    铺垫这么多,接下来终于要进入正题了:redo log为什么要用物理日志,比binlog好在哪?

    如果你看过redo log产生及流程,就会知道:写redo日志和写数据是两条互不干涉的流程(只有出现意外,服务重启时,落盘的日志才开始着手抢救不完整的数据库表文件)。

    也许就有人会有疑问:我知道redo日志写的快,也能保证日志的事务完整性。 可怎么保证另一边的数据落盘的完整性呢?如果数据只写了一半就中断了,手里虽然有完整的日志,如何知道从哪条数据开始恢复呢?

    redo log的巧妙就在于它是物理日志

    对物理日志来说,它根本不关心从哪里开始恢复数据,而是整块覆盖。不计算,直接写答案。这样的最终答案反复写几遍都无所谓。因为物理日志具有幂等性

    反过来,如果此时手里只有binlog,那就头大了:手里虽然有完整的解题流程,却不知道从哪一步开始补作业(好像一个学渣抄作业的过程中,忘记自己抄到哪一步了)。如果人工对账一条一条分析,也许可以补上。但这件事让机器去自动完成,就会变得非常不可靠。

    所以:物理日志实现了便捷可靠的修复数据

    总结

    1. 要处理速度 —> 有缓冲池就够了
    2. 要事务原子性 —> 加日志,WAL机制
    3. 要实现便捷可靠的完整恢复 —> 改为幂等日志(这里的物理日志或者说redo log)

    至于很多文章总会强调的:redo log把随机io变为顺序io,提高了写速度。
    我认为这个特性不值得特别说明。顺序io就是日志的天然特性,包括binlog在内的任何log都有这个特性(谁也不会写个日志,还东写一句,西写一句,搞一个复杂的数据结构去存)。
    这个逻辑是:因为要引入事务 —> 所以引入了日志 --> 日志较快的顺序io速度让事务完成的速度不至于太慢(注意,只是让事务完成的不至于太慢而已。如果不用事务,速度只会更快)
    所以说这就是引入事务之后,没有带来新的严重性能问题而已

    之前我们也许会把数据库表文件比作:仓库/海洋之类的。现在看来,这样的比喻还不够准确,这里比作草原/地板可能更准确。

    redo log就像一块块标记了位置的瓷砖。地板具体的裂纹在哪里 并不重要。想要快速完整修复。只要拿新瓷砖,整块整块的替换就好了。

    所以 redo log的关键特性就是:幂等性

  • 相关阅读:
    带你徒手完成基于MindSpore的CycleGAN实现
    Hexagon_V65_Programmers_Reference_Manual (51)
    63 x的平方根
    大唐杯学习笔记:Day10
    ros2移植Apollo和autoware规控算法可跑工程
    大神教你~Nginx网络服务
    React 入门:实战案例 TodoList 组件列表动态初始化
    oracle递归查询(start with connect by prior)以及 树形统计connect_by_root(子节点汇总到父节点)
    计算机网络复习06——应用层
    分享105个NET源码ASP源码,总有一款适合您
  • 原文地址:https://blog.csdn.net/yunduanyou/article/details/128188973