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

use*_*220 46 sql database logging transactions voltdb

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

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

Ren*_*nov 76

我认为最好改写一下:

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

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

一些基本术语:

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

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

在此输入图像描述

下一步是执行一些命令:

在此输入图像描述

请注意几个重要方面:

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

可以跳过某些中间状态,因为它足以具有一系列命令.

在此输入图像描述

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

  • 预写日志 - 中心概念是在对永久存储进行任何大量更新之前应记录状态更改.根据我们的想法,我们可以记录每个块的增量更改.
  • 命令记录 - 中心概念是仅记录命令,用于产生状态.

在此输入图像描述

这两种方法都有利弊.预写日志包含所有已更改的数据,命令日志将需要添加处理,但快速轻量级.

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用户可以获得相同类型的平流层性能数字,并具有额外的耐久性保证.