51

我阅读了有关 Voltdb 的命令日志。命令日志记录事务调用,而不是像预写日志那样记录每行更改。通过仅记录调用,命令日志保持在最低限度,从而限制了磁盘 I/O 对性能的影响。

谁能解释为什么 Voltdb 使用命令日志以及为什么 Postgres、MySQL、SQLServer、Oracle 等标准 SQL 数据库使用预写日志背后的数据库理论?

4

6 回答 6

82

我认为最好改写:

为什么新的分布式 VoltDB 使用命令日志而不是预写日志?

让我们做一个实验,假设您要编写自己的存储/数据库实现。毫无疑问,您已经足够先进,可以抽象文件系统并使用块存储以及一些额外的优化。

一些基本术语:

  • 状态:在给定时间点存储的信息
  • 命令:指示存储更改其状态

因此,您的数据库可能如下所示:

在此处输入图像描述

下一步是执行一些命令:

在此处输入图像描述

请注意几个重要方面:

  1. 一个命令可能会影响很多存储的实体,所以很多块会变脏
  2. 下一个状态是当前状态和命令的函数

可以跳过一些中间状态,因为有一个命令链就足够了。

在此处输入图像描述

最后,您需要保证数据的完整性。

  • Write-Ahead Logging - 中心概念是在对永久存储进行任何重大更新之前,应记录状态更改。按照我们的想法,我们可以记录每个块的增量更改。
  • 命令记录- 中心概念是仅记录用于生成状态的命令。

在此处输入图像描述

这两种方法各有利弊。Write-Ahead log 包含所有更改的数据,Command log 将需要附加处理,但速度快且轻量级。

VoltDB:命令记录和恢复

命令日志记录的关键是它记录事务的调用,而不是结果。通过仅记录调用,命令日志保持在最低限度,从而限制了磁盘 I/O 对性能的影响。

补充说明

SQLite:预写式日志记录

传统的回滚日志的工作原理是将原始未更改的数据库内容的副本写入单独的回滚日志文件,然后将更改直接写入数据库文件。

当指示提交的特殊记录附加到 WAL 时,会发生 COMMIT。因此,COMMIT 可以在不写入原始数据库的情况下发生,这允许读者在将更改同时提交到 WAL 的同时继续从原始未更改的数据库进行操作。

PostgreSQL:预写式日志记录 (WAL)

使用 WAL 会显着减少磁盘写入次数,因为只需要将日志文件刷新到磁盘以保证事务被提交,而不是事务更改的每个数据文件。

日志文件是按顺序写入的,因此同步日志的成本远低于刷新数据页的成本。对于处理涉及数据存储不同部分的许多小事务的服务器来说尤其如此。此外,当服务器正在处理许多小的并发事务时,日志文件的一个 fsync 可能足以提交许多事务。

结论

命令记录:

  1. 是比较快的
  2. 占地面积小
  3. 有更重的“重播”程序
  4. 需要频繁的快照

预写日志是一种提供原子性的技术。更好的命令日志记录性能还应该改进事务处理。1 英尺上的数据库

在此处输入图像描述

确认

VoltDB 博客:VoltDB 命令记录简介

命令日志记录优于 ARIES 样式日志记录的一个优点是可以在执行开始之前记录事务,而不是执行事务并等待日志数据刷新到磁盘。另一个优点是命令日志所需的 IO 吞吐量受用于中继命令的网络的限制,在 Gig-E 的情况下,这种吞吐量可以通过廉价的商品磁盘来满足。

重要的是要记住 VoltDB 是按其性质分布的。所以事务处理起来有点棘手,性能影响很明显。

VoltDB 博客:VoltDB 的新命令记录功能

VoltDB 中的命令日志由存储过程调用及其参数组成。在每个节点上创建一个日志,并且每个日志都被复制,因为所有工作都复制到多个节点。这会生成一个复制的命令日志,可以在重播时进行重复数据删除。因为 VoltDB 事务是强排序的,所以命令日志也包含排序信息。因此,回放可以按照原始事务运行的确切顺序发生,并具有 VoltDB 提供的完整事务隔离。由于调用本身通常小于修改后的数据,并且可以在提交之前记录下来,因此这种方法对性能的影响非常小。这意味着 VoltDB 用户可以获得相同类型的平流层性能数字,并具有额外的耐用性保证。

于 2013-01-10T14:58:22.237 回答
2

从 Postgres 的预写http://www.postgresql.org/docs/9.1/static/wal-intro.html和 VoltDB 的命令日志(您引用的)的描述中,我看不出有太大的区别。它似乎是具有不同名称的相同概念。

两者都只将日志文件同步到磁盘而不同步数据,以便可以通过重播日志文件来恢复数据。

VoltDB 的第 10.4 节解释说,他们的社区版本没有命令日志,因此无法通过 ACID 测试。即使在企业版中,我也看不到他们的事务隔离的细节(例如http://www.postgresql.org/docs/9.1/static/transaction-iso.html)需要让我对 VoltDB 感到满意像Postges一样严重。

于 2013-01-09T03:57:44.143 回答
2

使用 WAL,读者可以从未刷新的日志中读取页面。不对主数据库进行任何修改。使用命令日志,您无法读取命令日志。

因此,命令日志记录有很大不同。VoltDB 使用命令日志记录来创建恢复点并确保持久性,当然——但它正在实时写入主数据库存储(RAM)——伴随着所有伴随的锁定问题等。

于 2016-02-03T19:34:39.690 回答
0

它实际上只是粒度问题。它们在存储过程级别记录操作,大多数 RDBMS 在单个语句级别(和“更低”)记录。他们关于优势的宣传也有点牵强附会:

命令日志记录优于 ARIES 样式日志记录的一个优点是可以在执行开始之前记录事务,而不是执行事务并等待日志数据刷新到磁盘。

他们也必须等待命令被记录,它只是一个小得多的记录。

如果我没记错的话 VoltDB 的事务单元是一个存储过程。传统的 RDBMS 通常需要支持包含任意数量语句的 ad-hoc 事务,因此过程级日志记录是不可能的。此外,在传统的 RDBMS 中,存储过程通常不是真正的确定性(即,给定的参数+日志+数据总是产生相同的输出),它们必须这样才能工作。

然而,对于这种受约束的 RDBMS 模型,性能改进将是巨大的。

于 2013-05-18T21:49:07.470 回答
0

我的阅读方式如下:(我自己的看法)

此处描述的命令日志记录仅记录发生的事务,而不记录其中发生的事情或发生在它们身上的事情。好的,这就是神奇的部分......如果你想回滚,你需要恢复最后一个快照,然后你可以重播之后应用的所有事务(在上面的链接中描述)。因此,您可以有效地恢复备份并重新应用所有脚本,现在只有 VoltDB 为您自动化了它。

我看到的真正区别是您不能像使用普通事务日志那样在逻辑上回滚到某个时间点。正常事务日志(MSSQL、MySQL 等)可以轻松回滚到某个时间点(在正确的设置中),因为事务可以“反转”。

有趣的问题出现了 - 参考 pedz 的 pos,即使有命令日志,它是否总是通过 ACID 测试?会多读书...

补充:做了更多的阅读,我认为这对于非常大和繁忙的事务数据库来说不是一个好主意。当命令日志填满时,会自动创建数据库快照,以使您免受大事务日志和用于此的 IO 的影响?定期执行快照会产生大量 IO,而且您的内存也快到了极限。Alos,在我看来,您失去了轻松回滚到最后一个自动快照之前的时间点的能力 - 认为这将变得非常难以管理。

我宁愿坚持使用事务系统的事务日志。它已被证明并且有效。

于 2013-01-10T09:47:49.990 回答
0

在我开始解释之前,有几个术语:

日志方案:数据库使用影子分页、预写日志(WAL)等日志方案来实现并发、隔离和持久性(如何不同的主题)。

为了理解为什么 WAL 更好,让我们看一个影子分页的问题。在影子分页中,数据库使用数据库的主版本和影子版本,因此如果表大小为 10 亿并且缓冲池管理器没有足够的内存来保存内存中的所有元组(记录),则脏页在未提交事务之前不会将其写入主版本。

在此处输入图像描述

一旦提交了所有事务,就会切换标志并且影子版本成为主版本。在上图中,有Page 3 and Page 5一些旧的并且可以被垃圾收集。

  1. 这种方法的问题是留下了大量随机定位的碎片元组,这与顺序访问脏页相比要慢,这就是预写日志所做的。

  2. 使用 WAL 的另一个优点是运行时性能(因为您没有执行随机 IO 来刷新页面)但恢复时间较慢。然而,使用影子分页,恢复性能更快(偶尔需要)。

于 2020-09-15T03:35:53.437 回答