为什么SQL数据库在命令日志中使用预写日志?

我读了关于Voltdb的命令日志 。 命令日志logging事务调用,而不是像提前logging中的每一行更改。 通过仅logging调用,命令日志将保持最低限度,从而限制磁盘I / O对性能的影响。

任何人都可以解释为什么Voltdb使用命令日志的背后的数据库理论,为什么标准的SQL数据库,如Postgres,MySQL,SQLServer,甲骨文使用预写日志?

我认为最好改为:

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

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

一些基本术语:

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

所以你的数据库可能如下所示:

在这里输入图像说明

下一步是执行一些命令:

在这里输入图像说明

请注意几个重要方面:

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

一些中间状态可以被跳过,因为它足以产生一连串的命令。

在这里输入图像说明

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

  • 预写式日志logging – 中心概念是在对永久存储进行大量更新之前logging状态变化。 按照我们的想法,我们可以logging每个块的增量更改。
  • 命令logging – 中心概念是仅logging用于产生状态的命令。

在这里输入图像说明

这两种方法都有优点和缺点。 预写日志包含所有更改的数据,命令日志将需要添加处理,但是快速轻量。

VoltDB:命令logging和恢复

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

补充笔记

SQLite:预写日志

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

当指示提交的特殊logging被附加到WAL时,发生COMMIT。 因此,COMMIT可以在没有写入原始数据库的情况下发生,这允许读者在原始未改变的数据库中继续操作,同时将改变同时提交到WAL中。

PostgreSQL:预写日志(WAL)

使用WAL会导致磁盘写入数量大大减less,因为只有日志文件需要刷新到磁盘,以确保事务被提交,而不是事务更改的每个数据文件。

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

结论

命令logging:

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

预先写入logging是一种提供primefaces性的技术。 更好的命令logging性能还应改善事务处理。 一只脚的数据库

在这里输入图像说明

确认

VoltDB博客:介绍VoltDB命令logging

命令loggingARIES风格日志logging的一个优点是可以在执行开始之前logging事务,而不是执行事务并等待日志数据刷新到磁盘。 另一个优点是命令日志所需的IO吞吐量受到用于中继命令的networking的限制,并且在Gig-E的情况下,这种吞吐量可以由便宜的商品磁盘来满足。

记住,重要的是VoltDB是按其性质分配的。 所以交易处理起来有点棘手,并且性能影响是显而易见的。

VoltDB博客:VoltDB的新命令loggingfunction

VoltDB中的命令日志由存储过程调用及其参数组成。 日志在每个节点上创build,并且每个日志都被复制,因为所有的工作都被复制到多个节点上。 这会导致一个复制的命令日志,可以在重播时重置。 由于VoltDB事务强烈sorting,命令日志也包含订购信息。 因此,重播可以按原始事务的运行顺序进行,具有VoltDB提供的完整事务隔离。 由于调用本身通常比修改后的数据小,并且可以在提交之前进行logging,所以这种方法对性能的影响非常小。 这意味着VoltDB用户可以获得同样types的平stream层性能数据,并具有额外的耐用性保证。

从Postgres提供的http://www.postgresql.org/docs/9.1/static/wal-intro.html和VoltDB的命令日志(你所引用的)的描述来看,我看不出有什么不同。; 这似乎是一个不同的名字相同的概念。

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

VoltDB第10.4节解释说,他们的社区版本没有命令日志,所以它不会通过ACIDtesting。 即使在企业版本中,我也没有看到需要让我感到舒服的事务隔离的详细信息(例如http://www.postgresql.org/docs/9.1/static/transaction-iso.html),VoltDB是严格的邮政。;

我读的方式如下:(我自己的意见)

这里描述的命令日志logging只logging发生的事务,而不logging发生在它们中或发生的事务。 好吧,这里是魔术……如果你想回滚,你需要恢复最后一个快照,然后你可以重播所有在此之后应用的交易(在上面的链接描述)。 因此,有效地恢复备份并重新应用所有脚本,只有VoltDB现在已经为您自动执行了它。

与我看到的真正的区别是,你不能像正常的事务日志那样在逻辑上回滚到一个时间点。 正常的事务日志(MSSQL,MySQL等)可以很容易地回滚到一个时间点(在正确的设置中),因为事务可以被“颠倒过来”。

Interresting的问题出现了 – 指的是pedz的pos,即使使用命令日志,它是否会通过ACIDtesting? 会做更多的阅读…

添加:更多的阅读,我不认为这是一个很大的和繁忙的交易数据库的好主意。 当命令日志填满时,会自动创build一个数据库快照,以便将您从大事务日志和用于此的IO中拯救出来? 你将会在你的快照定期完成的情况下产生大量的IO数据,同时你也在使用你的记忆。 阿洛斯,在我看来,你失去了轻松回滚到最后一次自动快照之前的时间点的能力 – 认为这将变得非常棘手的pipe理。

我宁愿坚持交易logging系统的交易logging。 它被certificate是有效的。

它其实只是一个粒度问题。 他们在存储过程级别上logging操作,大多数RDBMSlogging在个别语句(和“下”)的级别。 另外,他们对优势的看法是一点点红鲱鱼:

命令loggingARIES风格日志logging的一个优点是可以在执行开始之前logging事务,而不是执行事务并等待日志数据刷新到磁盘。

他们必须等待logging的命令,它只是一个很小的logging。

如果我没有弄错,VoltDB的交易单位是一个存储过程。 传统的RDBMS通常需要支持包含任意数量的语句的临时事务,所以程序级的日志logging是不可能的。 此外,存储过程在传统的RDBMS中通常不是真正的确定性的(即给定的参数+日志+数据总是产生相同的输出),这对于这个工作是必须的。

不过,对于这个受限制的RDBMS模型来说,性能改进将是相当大的。

用WAL,读者从未刷新的日志中读取页面。 主数据库没有修改。 使用命令日志logging,您无法从命令日志读取。

命令日志logging因此非常不同。 VoltDB使用命令日志logging来创build恢复点并确保持久性 – 但是它正在实时写入主db存储区(RAM) – 所有伴随的locking问题等等。