据我理解,mysql完全可以充当InnoDB的重做日志。
那么,在启用了二进制日志之后,为什么InnoDB必须同时编写重做日志而不是仅仅切换到使用binlog呢?这难道不是大大降低了数据库写入性能吗?
除了简化设计和实现之外,这样做有什么好处吗?
AFAIK,为了在保证符合ACID的同时启用两个日志,将出现以下问题:
因此,所有其他产品似乎只使用一组日志( Server称为事务日志、ORACLE称为重做日志和PostgreSQL称为WAL)来完成所有相关工作。是否只有MySQL必须同时打开两组日志以确保ACID遵从性和强大的一致主从复制?
是否有一种方法可以实现ACID遵从性和强一致性的半同步复制,而其中只有一种是启用的?
发布于 2019-09-18 08:43:47
这是一个有趣的话题。很长一段时间以来,我一直主张将InnoDB预写日志和二进制日志合并。最大的动机是,同步两个独立日志的需求将消失。不过,恐怕这种情况不会在短期内发生。
在MariaDB,我们正在采取一些步骤来减少fsync()开销。通过持久的binlog恢复MDEV-18959引擎事务的思想是确保binlog永远不会在InnoDB重做日志后面,这样就允许在binlog文件上只使用一个fsync()调用就可以进行持久的、安全的事务提交。
当binlog实现逻辑日志时,InnoDB重做日志实现物理日志记录(包括对实现撤销日志和索引树的持久数据页的更改)。正如我在深度潜水: InnoDB事务和写入路径中解释的那样,用户事务被划分为多个小型事务,每个事务都可以原子地修改多个数据页。
重做日志是对多个数据页进行原子化更改的“胶水”。我认为重做日志对于实现就地更新数据结构的原子更改是绝对必要的。仅附加数据文件结构(如LSM树)可以是自己的日志,而不一定需要单独的日志。
对于包含辅助索引的InnoDB表,每个行操作实际上被划分为多个小事务,分别对每个索引进行操作。因此,事务层需要更多的“胶水”,使表的索引彼此一致。该“胶”由撤消日志提供,该日志在持久数据页中实现。
InnoDB预先执行对索引页的更改,提交是一项快速操作,只需更改撤销日志头中事务的状态。但是回滚是非常昂贵的,因为撤消日志必须向后重放(并且将编写更多的重做日志来覆盖这些索引页的更改)。
在MariaDB服务器中,MyRocks是另一个事务存储引擎,它做的正好相反:内存中的缓冲区更改一直到结束,在提交时将它们应用到数据文件中。这使得回滚非常便宜,但是事务的大小受到可用内存量的限制。我已经了解到,MyRocks可以按您提议的方式工作。
https://stackoverflow.com/questions/57983490
复制相似问题