有人可以解释一下为什么Voltdb使用命令日志以及标准的SQL数据库(如Postgres、MySQL、SQLServer、Oracle)为什么使用预写式日志吗?请阐述背后的数据库理论。
新的分布式 VoltDB 为什么使用命令日志而不是预写式日志?
让我们进行一个实验,想象一下你要编写自己的存储/数据库实现。毫无疑问,您已经足够先进,可以抽象出文件系统,并使用块存储以及一些额外的优化。
一些基本术语:
因此,您的数据库可能如下所示:
使用WAL可大幅减少磁盘写入次数,因为只需将日志文件刷新到磁盘即可保证事务提交,而不是将事务更改的每个数据文件都刷到磁盘。
日志文件按顺序写入,因此同步日志的成本比刷新数据页的成本要低得多。这对于处理许多小事务并涉及数据存储不同部分的服务器尤其如此。此外,当服务器处理许多小型并发事务时,一次fsync日志文件可能足以提交多个事务。
结论
命令记录:
写前日志是提供原子性的技术。更好的命令记录性能也应该改善事务处理。1英尺数据库
确认
与ARIES风格日志记录相比,命令日志的一个优点是可以在执行之前记录事务,而不是执行事务并等待日志数据刷新到磁盘。另一个优点是命令日志所需的IO吞吐量由中继命令使用的网络限制,并且在Gig-E的情况下,这种吞吐量可以通过廉价的商品磁盘满足。
重要的一点是要记住VoltDB本质上是分布式的。因此,处理事务有些棘手,性能影响是明显的。
VoltDB的命令日志包括存储过程调用及其参数。每个节点都会创建一个日志,并且每个日志都会被复制,因为所有工作都会被复制到多个节点。这导致了一个可重放的复制命令日志。由于VoltDB事务是强有序的,因此命令日志也包含排序信息。因此,重放可以按照原始事务运行的确切顺序进行,具有VoltDB提供的完整事务隔离性。由于这些调用本身通常比修改的数据小,并且可以在提交之前记录,因此这种方法对性能影响非常小。这意味着VoltDB用户可以获得相同类型的极高性能数字,并获得额外的耐用性保证。random()
?如果有,这样的命令如何表达?我认为它会在接收节点上实现,然后进行复制? - Byron Ruth这实际上只是一个粒度问题。他们在存储过程级别记录操作,大多数关系型数据库管理系统在单个语句(和更低级别)的级别记录日志。此外,他们关于优势的介绍有点误导:
与ARIES风格日志记录相比,命令日志记录的一个优点是可以在执行开始之前记录事务,而不是执行事务并等待日志数据刷新到磁盘。
他们也必须等待命令被记录,只是记录的记录要小得多。
如果我没记错,VoltDB的事务单位是存储过程。传统的关系型数据库管理系统通常需要支持包含任意数量语句的即席事务,因此存储过程级别的日志记录是不可能的。此外,在传统的关系型数据库管理系统中,存储过程通常并不真正确定(即给定参数+日志+数据总是产生相同的输出),而这对于此工作来说是必须的。
尽管如此,对于这种受限制的关系型数据库管理系统模型,性能改进将是巨大的。
我对此的理解如下(仅代表个人观点):
如此描述的命令日志仅记录事务发生的情况,而不记录其内部或外部发生的情况。好的,这里有一个神奇的部分...如果您想要回滚,则需要恢复最后一个快照,然后可以重放在此之后应用的所有事务(在上面的链接中描述)。因此,实际上您正在恢复备份并重新应用所有脚本,只是现在VoltDB已经为您自动化了。
我看到的真正区别是,您无法像普通事务日志(MSSQL、MySQL等)那样逻辑地回滚到某个时间点。普通事务日志可以轻松地回滚到某个时间点(在正确的设置中),因为事务可以“撤消”。
引起兴趣的问题出现了——参考pedz的帖子,即使使用命令日志,它是否始终能通过ACID测试?将会进行更多阅读...
补充:我读了更多的资料,我认为这对于非常大和繁忙的事务性数据库不是一个好主意。当命令日志填满时,会自动创建一个DB快照,以节省大量的事务日志和IO?你将在定期间隔内产生大量的IO量,并且还将使用您的内存到极限。此外,在我看来,您失去了轻松回滚到上一个自动快照之前某个时间点的能力 - 我认为这将变得非常棘手。
我宁愿坚持使用事务日志来处理事务系统。它已经被证明是有效的。
一旦所有交易都被提交,标志就会切换,影子版本就成为主版本。在上面的图表中,有Page 3和Page 5
是旧的,可以进行垃圾回收。
这种方法的问题是留下了大量碎片化的元组,随机分布,与顺序访问脏页相比速度较慢,这就是Write Ahead Log所做的。
使用WAL的另一个优点是运行时性能(因为您不需要随机IO来刷新页面),但恢复时间较慢。而使用影子分页,恢复性能更快(偶尔需要)。
Voltdb
如何实现“撤销”功能?如果我执行UPDATE some_table SET some_column=2
,那么仅仅知道这个命令是不允许我回滚更改的吗? - Martin Smith