3

我正在编写一个简单的应用程序,其中包含 24 个项目的哈希值,以便在程序执行中保持不变,因此 Berkeley DB (DBM) 应该非常适合这项任务。

这只是为了好玩。

但我想知道是否使用它(与 Ruby 一起使用),然后当用户按下 CTRL-C 时,执行就会停止。这种情况下,是不是数据都乱了?

例如,如果 DB 中的值为 63,我将其加 1(变为 64)

63 =  111111 (in binary)  
64 = 1000000 (in binary)

那么,当“最重要的”1 被写入但 0 还没有被写入时,CTRL-C 是否会发生?在这种情况下,DB 中的值将是 127 而不是 63 或 64。如果不是 Ruby 而是 C 语言,并且用户使用“关闭窗口”或“杀死”来终止进程怎么办?想一想,硬盘驱动器可能一次将这个字节(或4字节)全部写入硬盘表面,所以这种情况不应该发生。

如果 CTRL-C 不会导致这种情况发生,那么停电或我踢电源插头可能会导致这种情况发生?例如,当值第一次缓存在 RAM 中,当它被写入硬盘时,我踢了电源插头,硬盘驱动器在写入 0 之前就断电了。我知道百万分之一,这不会发生,但这只是好奇的问题。

另一方面,如果我的脚本是

  1. 减少硬币价值
  2. 在他的库存中给用户一个“汉堡包”

然后当用户按下 CTRL-C 时,它恰好发生在上面的 (1) 和 (2) 之间,那么用户将拥有更少的硬币,并且不会得到汉堡包。

为了防止这一切发生,那就是使用SleepyCat、SQLite或MySQL的事务方法,这些都不会发生?

4

1 回答 1

2

没有一个好的数据库系统(包括 Berkley DB 的类别)可以按照您建议的方式中断,并部分更新值。当您按 control-c 时,您不能中断 CPU 中途指令。中断总是有一定程度的粒度,编写良好的数据库利用这一事实来防止数据库处于不一致状态。

断电时存在数据损坏和丢失的可能性,但数据是否会丢失或损坏的细节更多地与存储数据库文件的文件系统有关。例如,一个好的日志文件系统会在“日志”中写入它要做什么,然后执行它,然后在日志中写入它已经完成的操作。因此,如果它在写入操作期间断电,例如,它会查看其日志以查看在允许访问文件系统之前是否需要完成任何事情。这是一种过度简化,但您可以通过查看 ext3 上的 wikipedia 来获取详细信息,例如。

于 2009-11-25T05:38:53.737 回答