2012-10-20 22 views
7

我正在写一些软件来处理非常关键的数据,并且需要知道我到底需要做什么来实现耐久性。需要什么才能在Linux上持久?

无论我看到的是矛盾的信息,所以我会很感激任何见解。

我有三种写入磁盘的方式。

  • 使用O_DIRECT | O_DSYNC,并预先写入,然后写入512字节 - 16 MB块。

  • 使用O_DIRECT,预先写入,然后写入512字节块,并根据需要定期调用fdatasync。

  • 使用内存映射文件,我必须定期调用msync(...,MS_SYNC | MS_INVALIDATE)。

这是所有的ext4默认标志。

对于所有这些,是否有可能丢失数据(在写入或同步返回之后)或由于电源故障,紧急情况,崩溃或其他原因而损坏?

如果我的服务器死于中间pwrite,或者在pwrite的开始和fdatasync的结束之间,或者正在更改的映射内存和msync之间,我可能会混合使用新旧数据,或者它会是一个还是另一个?我希望我的个人pwrite调用是原子的,并且是有序的。是这样吗?如果他们跨越多个文件,是这种情况吗?所以,如果我用O_DIRECT |写入O_DSYNC到A,然后是O_DIRECT | O_DSYNC到B,我保证,无论发生什么,如果数据在B中,它也在A中?

fsync是否甚至可以保证数据的写入? This说不,但是我不知道自那以后事情是否改变了。

ext4的日记完全解决了this SO answer说存在的损坏块的问题吗?

我目前正在通过调用posix_fallocate来生长文件,然后ftruncate。这些都是必要的,它们足够吗?我认为ftruncate实际上会初始化分配的块以避免these issues

为了增加混淆,我在EC2上运行这个,我不知道这是否会影响任何东西。虽然它很难测试,因为我无法控制它被关闭的程度。

+1

数据总是会丢失,至少是因为硬件(或软件)故障。您应该备份(即复制)它,或者至少计算一些校验和(以便能够验证或使其无效)。我不确定玩系统调用技巧是否足够。我会尽力复制和校验关键数据,也许会考虑交易。 –

+2

@BasileStarynkevitch在上面的图层中,数据仅在两个节点已确认时才会被视为已写入,并且我们还会每日拍摄快照。我们认为这是足够的,它只是确保在确认这是问题之前将数据实际写入HDD。 – Max

回答

3

对于所有这些,数据是可能丢失(写入或同步返回后)还是由电源故障,恐慌,崩溃或其他任何损坏?

绝对。

fsync是否甚至可以保证数据的写入?这不说,但是我不知道自那以后事情是否改变了。

不是。答案是依赖于设备,可能依赖于文件系统。不幸的是,该文件系统可能是“实际”存储设备上方的层和层。 (例如。md,lvm,fuse,loop,ib_srp等)。

虽然它很难测试,因为我无法控制它被关闭的程度。

的确如此。但你可能仍然可以使用NMI或sysrq-trigger来创建一个非常突然的停顿。

相关问题