为啥在启用 mysql binlog 后我们还需要 innodb redo log?

     2023-02-16     168

关键词:

【中文标题】为啥在启用 mysql binlog 后我们还需要 innodb redo log?【英文标题】:Why we still need innodb redo log when mysql binlog has been enabled?为什么在启用 mysql binlog 后我们还需要 innodb redo log? 【发布时间】:2020-01-18 20:43:27 【问题描述】:

在我的理解中,mysql binlog 完全可以作为 InnoDB 的 redo log。

那么,在启用binlog之后,为什么InnoDB非要切换到使用binlog,还要同时写redo log呢?这不会显着降低数据库写入性能吗?

除了简化设计和实现之外,这样做有什么好处吗?

AFAIK,在保证 ACID 合规性的情况下同时启用两个日志,会出现以下问题:

    每条具有相同含义的日志记录必须分别写入两次。 每次提交事务或事务组时刷新两个日志。 为确保两个日志文件之间的一致性,使用了复杂且低效的方式,例如 XA (2PC)。

因此,所有其他产品似乎只使用一组日志(SQL Server 称为 Transaction log,ORACLE 称为 redo log,PostgreSQL 称为 WAL)来完成所有相关工作。是不是只有 MySQL 必须同时打开两组日志才能保证 ACID 合规性和强一致性主从复制?

有没有办法实现 ACID 合规性和强一致性半同步复制,同时只启用其中一个?

【问题讨论】:

【参考方案1】:

这是一个有趣的话题。一直以来,我一直在提倡将 InnoDB write-ahead log 和 binlog 合并的想法。这样做的最大动机是不再需要同步两个单独的日志。但是,恐怕这不会很快发生。

在 MariaDB,我们正在采取一些措施来减少 fsync() 开销。 MDEV-18959 Engine transaction recovery through persistent binlog 的想法是保证 binlog 永远不会落后于 InnoDB 重做日志,从而允许在 binlog 文件上仅通过一次 fsync() 调用进行持久的、崩溃安全的事务提交。

虽然 binlog 实现了逻辑日志记录,但 InnoDB 重做日志实现了物理日志记录(涵盖对实现撤消日志和索引树的持久数据页面的更改)。正如我在M|18 Deep Dive: InnoDB Transactions and Write Paths 中解释的那样,一个用户事务分为多个小事务,每个小事务可以原子地修改多个数据页。

重做日志是对多个数据页进行原子更改的“粘合剂”。我认为重做日志对于实现就地更新数据结构的原子更改是绝对必要的。仅追加的数据文件结构(例如 LSM 树)本身可以是日志,不一定需要单独的日志。

对于包含二级索引的 InnoDB 表,每一个单独的行操作实际上都被划分为多个小事务,分别对每个索引进行操作。因此,事务层需要更多的“粘合剂”,使表的索引彼此一致。这种“胶水”由撤消日志提供,它在持久数据页中实现。

InnoDB 预先对索引页进行更改,commit 是一种快速操作,只是在 undo log header 中更改事务的状态。但是回滚是非常昂贵的,因为撤消日志必须向后重放(并且将写入更多的重做日志来覆盖那些索引页面的更改)。

在 MariaDB Server 中,MyRocks 是另一个事务性存储引擎,它的作用正好相反:在内存中缓冲更改直到最后,并在提交时将它们应用到数据文件。这使得回滚非常便宜,但事务的大小受可用内存量的限制。我知道 MyRocks 可以按照您建议的方式工作。

【讨论】:

您好,Marko,感谢您的精彩而全面的回答。但是无论你使用哪种 ACID 兼容的存储引擎,binlog 都会导致额外的写入,对吧?似乎只有禁用binlog,直接通过redo log进行复制,才能完全避免这些额外的开销?我发现了这个:medium.com/@Alibaba_Cloud/…mariadb等主流发行版中是否有可能出现类似的功能? @ASBai 你是对的。多年来,我一直提倡将所有日志事件写入单个文件的想法。在jira.mariadb.org/browse/MDEV-12353 中,我正在研究一种新的 InnoDB 重做日志格式,该格式允许添加“外部”日志事件。解析和应用日志的更简单的代码也可以更容易地实现物理复制(没有二进制日志)。 我认为这是一个很大的改进,我必须投赞成票:-)

mysql如何解决数据一致性

...个流程变成了下面这样:首先,master和至少一个slave都要启用semi-syncreplication模式;某个slave连接到master时,会主动告知当前自己是否处于semi-sync模式;在master上提交事务后,写入binlog后,还需要通知至少一个slave收到该事务,等... 查看详情

mysql中的日志“binlog”的三种格式(代码片段)

MySQL中的日志比较重要的有binlog(归档日志)、redolog(重做日志)以及undolog;1.binlogbinlog我们中文一般称作归档日志,当我们搭建MySQL主从的时候就离不开binlog;binlog是MySQLServer层的日志,而不是存储引擎自带的日志,它记录了... 查看详情

mysqlbinlog中的为啥会有rollback

当启动Binlog后,事务会产生BinlogEvent,这些Event被看做事务数据的一部分。因此要保证事务的BinlogEvent和InnoDB引擎中的数据的一致性。所以带Binlog的CrashSafe要求MySQL宕机重启后能够保证:-所有已经提交的事务的数据仍然存在。-所... 查看详情

mysql主从复制重新启用需要注意啥

参考技术A主机的mysql重启,但是你的从机mysql肯定是没重启才出现binlog索引不一致的现象,我认为是,从机mysql在主机重启之前slave_io_running线程始终保持和主机通信,传输binlog的更新。当主机挂掉之后,slave_io_running一直等待,状... 查看详情

mysql只有binlog怎么恢复

有完整备份的话,先用完整备份还原下,然后在用binlog恢复从完整备份到当前时间点的数据。如果没有完整备份的话,使用binlog也可以恢复,不过10G的数据可能需要很长的时间。相关语法如下:mysql-hlocalhosttest<完整备份mybinlog-... 查看详情

为啥我们必须在查询命令后关闭 MySQL 数据库?

】为啥我们必须在查询命令后关闭MySQL数据库?【英文标题】:WhydowehavetoclosetheMySQLdatabaseafteraquerycommand?为什么我们必须在查询命令后关闭MySQL数据库?【发布时间】:2013-10-2219:39:33【问题描述】:我是首发。我想知道如果我们不... 查看详情

为啥我们需要xampp在mysql中创建数据库??(用java连接它)

】为啥我们需要xampp在mysql中创建数据库??(用java连接它)【英文标题】:whydoweneedxampptocreatedatabaseinmysql??(connectingitwithjava)为什么我们需要xampp在mysql中创建数据库??(用java连接它)【发布时间】:2014-08-2711:30:30【问题描述... 查看详情

为啥我们有 pack_sequence() 时还需要 pack_padded_sequence()?

】为啥我们有pack_sequence()时还需要pack_padded_sequence()?【英文标题】:Whydoweneedpack_padded_sequence()whenwehavepack_sequence()?为什么我们有pack_sequence()时还需要pack_padded_sequence()?【发布时间】:2020-05-1306:21:51【问题描述】:在阅读了this问... 查看详情

通过binlog恢复数据

参考技术AMySQL的二进制日志binlog可以说是MySQL最重要的日志,它记录了所有的DDL和DML语句(除了数据查询语句select、show等),以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。binlog的主要目... 查看详情

架构运维篇:mysql8.0启用binlog支持

...数据执行的问题,找了团队DBA发现云上的MySQL默认是没有启用BinLog支持。小编研究了一下很简单,不过中间也遇到一些坑可以给大家分享一下。环境说明:MySQL:8.0备注:通过宝塔工具快速安装。第一步:修改/etc/my.conf文件#binlog_... 查看详情

为啥启用分析后我的程序运行得更快?

】为啥启用分析后我的程序运行得更快?【英文标题】:WhydoesmyprogramrunwayfasterwhenIenableprofiling?为什么启用分析后我的程序运行得更快?【发布时间】:2009-12-2622:57:07【问题描述】:我有一个运行速度很慢的程序(即使在发布时... 查看详情

如何查看mysql的binlog数据

binlog,即二进制日志,它记录了数据库上的所有改变.改变数据库的SQL语句执行结束时,将在binlog的末尾写入一条记录,同时通知语句解析器,语句执行完毕.binlog格式基于语句,无法保证所有语句都在从库执行成功,比如update...limit1;基于... 查看详情

mysql中redo与binlog顺序一致性问题

...的几个问题去学习复制到底是怎样工作的。为什么MySQL有binlog,还有redolog?事 查看详情

phpstudy启动后为啥mysql无法启动

phpstudy中apache或mysql无法启动phpstudy中apache或mysql无法启动,启动一下没了明显端口被占用了,假如我们需要确定谁占用了我们的80端口,3306端口对网站来说,网络apatche服务器是默认80,数据库mysql是3306端口占有两种解决方法:法1:把... 查看详情

为啥在启用 ARC 的项目中不需要维护保留计数

】为啥在启用ARC的项目中不需要维护保留计数【英文标题】:WhymaintainingretaincountisnotrequiredinARCenabledproject为什么在启用ARC的项目中不需要维护保留计数【发布时间】:2015-07-2805:54:34【问题描述】:保留计数是Objective-C中管理内存... 查看详情

mysql误删数据后切勿跑路

...可以使用Flashback工具。Flashback恢复数据的原理是通过修改binlog内容,拿回原库进行回放,前提是binlog_format=row和binlog_row_image=FULL。在使用Flashback进行恢复的时候,不建议在主库上进行操作,比较安全的做法是恢复出一个备份,或... 查看详情

为啥我定义了参数后,这个模型还需要先调用'build()'?

】为啥我定义了参数后,这个模型还需要先调用\\\'build()\\\'?【英文标题】:Whydidthismodelstillneedcalling\'build()\'firstlywhenIhavedefinedparameters?为什么我定义了参数后,这个模型还需要先调用\'build()\'?【发布时间】:2022-01-1500:33:21【问... 查看详情

当我们已经拥有更强大的向量时,为啥还需要堆栈?

】当我们已经拥有更强大的向量时,为啥还需要堆栈?【英文标题】:Whydoweneedstackswhenwealreadyhavevectorswhichareevenmorepowerful?当我们已经拥有更强大的向量时,为什么还需要堆栈?【发布时间】:2021-11-0311:09:18【问题描述】:在C++STL... 查看详情