标签: fsync

在Linux上持久耐用需要什么?

我正在编写一些软件来处理非常关键的数据,并且需要知道我需要做些什么来实现持久性.

我看的每个地方都是矛盾的信息,所以我很欣赏任何见解.

我写入磁盘有三种方法.

  • 使用O_DIRECT | O_DSYNC,pread'ing然后pwrite'ing 512字节 - 16 MB块.

  • 使用O_DIRECT,pread'ing然后pwrite'ing 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甚至可以保证数据的写入吗?不是说,但我不知道从那时起事情是否发生了变化.

ext4的日志记录是否完​​全解决了这个SO答案所存在的腐败块的问题?

我目前通过调用posix_fallocate然后ftruncate来增长文件.这些都是必要的,它们是否足够?我认为ftruncate实际上会初始化已分配的块以避免这些问题.

为了给混音添加混乱,我在EC2上运行它,我不知道这是否会影响任何东西.虽然它很难测试,因为我无法控制它被关闭的积极程度.

linux posix mmap fsync durability

9
推荐指数
2
解决办法
762
查看次数

为什么fsync()在Linux内核3.1.*上比在内核3.0上花费更多的时间

我有一个测试程序.在Linux内核3.1.*上大约需要37秒,但在内核3.0.18上只需要大约1秒钟(我只需要在同一台机器上替换内核).请给我一个如何在内核3.1上改进它的线索.谢谢!

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>


int my_fsync(int fd)
{
    // return fdatasync(fd);
    return fsync(fd);
}


int main(int argc, char **argv)
{
    int rc = 0;
    int count;
    int i;
    char oldpath[1024];
    char newpath[1024];
    char *writebuffer = calloc(1024, 1);

    snprintf(oldpath, sizeof(oldpath), "./%s", "foo");
    snprintf(newpath, sizeof(newpath), "./%s", "foo.new");

    for (count = 0; count < 1000; ++count) {
    int fd = open(newpath, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU);
    if (fd == -1) {
        fprintf(stderr, "open …
Run Code Online (Sandbox Code Playgroud)

fsync linux-kernel

7
推荐指数
1
解决办法
1997
查看次数

Windows fsync(FlushFileBuffers)与大文件的性能

从确保数据在磁盘上的信息(http://winntfs.com/2012/11/29/windows-write-caching-part-2-an-overview-for-application-developers/),即使是在例如停电,似乎在Windows平台上,您需要依靠其"fsync"版本FlushFileBuffers来最好地保证缓冲区实际上是从磁盘设备缓存刷新到存储介质本身.如果此信息正确,则FILE_FLAG_NO_BUFFERINGwith 的组合FILE_FLAG_WRITE_THROUGH不会确保刷新设备缓存,而只会影响文件系统缓存.

鉴于我将使用相当大的文件,需要"事务性地"更新,这意味着在事务提交结束时执行"fsync".所以我创建了一个小应用来测试这样做的性能.它基本上使用8次写入执行一批8个内存页大小的随机字节的顺序写入,然后刷新.批处理循环重复,在每隔这么多的书面页面之后记录性能.此外,它有两个可配置的选项:在开始页面写入之前,对刷新进行fsync以及是否将字节写入文件的最后位置.

// Code updated to reflect new results as discussed in answer below.
// 26/Aug/2013: Code updated again to reflect results as discussed in follow up question.
// 28/Aug/2012: Increased file stream buffer to ensure 8 page flushes.
class Program
{
    static void Main(string[] args)
    {
        BenchSequentialWrites(reuseExistingFile:false);
    }
    public static void BenchSequentialWrites(bool reuseExistingFile = false)
    {
        Tuple<string, bool, bool, bool, bool>[] scenarios = new Tuple<string, bool, bool, bool, bool>[]
        { …
Run Code Online (Sandbox Code Playgroud)

c# windows performance fsync

7
推荐指数
2
解决办法
5677
查看次数

寻求的解释/信息:Windows使用"fsync"(FlushFileBuffers)写入I/O性能

这个问题是我发布的早期问题的后续跟进:Windows fsync(FlushFileBuffers)与大文件的性能.在哪里我找到了可能的解决方案,但也有新问题.

在对不同的情节进行基准测试时,我发现了许多令人惊讶的结果.我希望有人可以帮助解释或指出我解释这些结果的信息方向.

这个基准测试的作用是按顺序将8个页面(32 K)的随机块(大4096字节)写入文件,然后刷新写入.它总共写了200000页,总计800 MB和25000次刷新.在开始写入之前,文件的大小设置为其最终长度.

它支持总共4个选项,其中运行所有组合:

  • FlushFileBuffers在写入批处理或正常刷新(NS)之后执行"fsync"/ 操作(FS).
  • 在开始写入(LB)或将文件保留为空(E)之前将单个字节写入文件的最后位置.
  • 使用正常缓冲的写入(B)或无缓冲/写通式(WT)写入(使用FILE_FLAG_NO_BUFFERING和FILE_FLAG_WRITE_THROUGH).
  • 直接写入文件流,即通过文件句柄(F)或使用存储器映射(MM)间接写入文件.

下表总结了我对我的系统(具有慢速主轴磁盘的64位Win 7笔记本电脑)的所有这些选项组合的发现.

所有选项组合的基准测试结果

我发现的是,"fsynced"缓冲写入的性能与文件的一个令人难以置信的低吞吐量的大小,使大型文件这样做不可行组合呈指数下降.如果文件的最后一个字节写入(选项LB),吞吐量甚至更低,所以我担心在随机而不是顺序写入情况下,性能将更加显着.

然而令人惊讶的是,对于无缓冲/写入I/O,吞吐量保持不变,与文件大小无关.最初(前100-200 MB)它的吞吐量低于缓冲写入,但之后平均吞吐量迅速赶上并且完成写入800 MB的速度更快.更令人惊讶的是,如果文件的最后一个字节写入,吞吐量会增加2倍.

通过内存映射文件写入文件时,可以看到相同的指数性能下降,同样在使用无缓冲/写入标志打开文件的情况下.在这里,如果文件有一个字节写入其最后位置,性能会更差.

UPDATE 基于霍华德的解释这里这里,我重新测试,而无需启动之前写创建一个新的文件(即打开现有的,充分的书面文件,并覆盖它).我已更新原始问题中的代码,以反映此测试所做的更改.结果部分符合他对Linux的解释和发现.但有一些值得注意的例外.下表给出了结果,红色亮点显著的变化,蓝色的亮点,其中的变化并没有出现,这是令人惊讶的(即不符合预期,如果在霍华德的解释中提到的效应在作怪唯一的).

覆盖现有文件时的结果

对于具有"fsync"刷新的缓冲写入文件(即不通过memmap),性能现在已经从指数衰减变为恒定趋势.但是,它现在比以前的测试场景需要更长的时间.吞吐量是一个恒定的1.5 MB/s,在它开始之前大约20 MB/s,指数衰减到1.5 MB/s左右.看起来可能的解释是文件元数据也会在每次刷新时被刷新,从而导致完整的磁盘革命以寻找元数据的位置.

对于"直写"到文件场景,写入最后一个字节的结果现在是相同的,与霍华德的解释所期望的一致.

然而,对存储器映射的写入,有一个值得注意的例外,并没有真正改变,这是令人惊讶的.它们在写入性能方面仍然表现出相同的指数衰减(从大约20 MB/s衰减到1.8 MB/s开始).这表明正在发挥不同的机制.一个值得注意的例外是如果基础文件是在没有FILE_FLAG_WRITE_THROUGH的情况下创建的,则执行"fsync"刷新.此方案现在显示恒定(差)性能,吞吐量约为1.6 MB/s.由于我有些疑惑,我多次重复这种情况,每次给出相同的结果.

为了找出多一点,我也使用较小的文件(50000页,共计200 MB),以确认,该FSYNC性能(缓冲I/O)实际上是不依赖于文件大小重新运行该测试.结果显示如下,值得特别注意的结果用红色突出显示.

较小文件的结果

这些结果与较大文件的结果很好地相关.值得注意的变化是,对于那些突出显示的内容,写入更有效,它们似乎达到了大约7 MB/s的限制.

总结为基于对我的系统的观察到目前为止的高度推测性结论:

  • "FSYNC"在Windows上使用缓冲IO文件(即没有FILE_FLAG_WRITE_THROUGH标志)的性能呈指数和已经写入到文件的字节数减少.原因似乎是每次都需要刷新文件元数据,这会导致磁盘搜索到文件的开头.
  • 写入内存映射文件时,Windows上的"fsync"性能也会以指数方式降低性能.我目前没有解释造成这种情况的确切机制.

鉴于这种观察到的性能,至少在我的用例中,这两个I/O选项并不代表可行的解决方案.

根据Greg的建议,我将在关闭Windows磁盘缓存的情况下重新运行测试,并且我还将运行Howard提供的基准代码,以排除由于我自己的错误而导致结果偏差的可能性.

更新2 我已完成测试,目前正在编译结果.为了不写"完整的历史",我将用结果,发现和一些结论的摘要替换这个问题的当前内容.霍华德在这个问题上的答案,以及在.NET代码旁边运行他的c基准代码的能力是最有用的.应用程序的结果相关性很好.Rlb的回答帮助我更好地理解了与磁盘相关的"合理数字".谢谢.

问题的一部分仍未得到答复.特别与在写入存储器映射时观察到的降低(和依赖于文件大小)性能有关.这可能与寻找/元数据刷新,但目前尚不清楚,我为什么/如何.

c# windows performance mmap fsync

7
推荐指数
1
解决办法
1526
查看次数

如果之前返回错误,再次调用Win32 FlushFileBuffers()函数是否安全?

我看了一下这个话题:"PostgreSQL与fsync.如何将PostgreSQL错误地使用fsync 20年,以及我们将采取什么措施." 通过https://fosdem.org/2019/schedule/event/postgresql_fsync/,并阅读https://lwn.net/Articles/752063/作为背景.

如果你调用fsync()并且它失败了,那么真正的简短和简化的摘要是使用Linux,不要认为你可以再次调用fsync()来修复它,因为第二次调用成功并且你将在磁盘上损坏数据(失败的缓冲区缓存页面在第一次失败的呼叫后标记为干净).关于为什么会发生这种情况有很多细节(支持取出USB的情况 - 你不想重试并保持永远无法成功的脏缓冲区缓存页面).

FlushFileBuffers()在这种情况下如何表现?我对通过CIFS访问的文件特别感兴趣,因为更可能出现故障.

此外,鉴于操作系统可以尝试在后台随时将脏缓冲区缓存页写入稳定存储,用户登陆程序如何通过Win32 API获取这些故障?

windows filesystems winapi fsync

7
推荐指数
0
解决办法
269
查看次数

SD卡写性能

我正在编写一个小应用程序,它在SD卡上以恒定速率写入jpeg图像.我选择了一个EXT3文件系统,但是在EXT2文件系统中观察到了相同的行为.

我的写循环看起来像这样:

get_image()
fwrite()
fsync()
Run Code Online (Sandbox Code Playgroud)

或者像这样:

get_image()
fopen() 
fwrite()
fsync()
fclose()
Run Code Online (Sandbox Code Playgroud)

我还显示了一些时序统计信息,我可以看到我的程序有时会被阻止几秒钟.平均速率仍然很好,因为如果我将传入的图像保持为fifo,那么我将在这样的停顿之后的短时间内写出许多图像.您知道操作系统是否存在问题,或者它是否与SD卡本身有关?我怎么能接近实时?我不需要强大的实时性,但是停滞几秒钟是不可接受的.

一些精度:是的,每个文件后都需要fsync,因为我希望图像在磁盘上,而不是在某些用户或内核缓冲区中.没有fsyncing,我有更好的吞吐量,但仍然是不可接受的失速.我不认为这是一个缓冲区问题,因为第一次失速发生在写入50 MB之后.根据手册页,fsync正是为了确保没有数据缓冲.

关于平均写入速率的精确度:我正在以我正在使用的卡可持续的速率写入.如果我在等待fsync完成时堆叠传入的图像,那么在此停顿之后写入传输速率将增加,我将很快回到平均速率.平均传输速率约为1.4 MB/s.

系统是一台现代笔记本电脑运行ubuntu 8.04与库存记录(2.6.24.19)

linux real-time sd-card fsync ext3

5
推荐指数
1
解决办法
1万
查看次数

java.io.FileDescriptor.sync() 是否在 Linux 上同步目录?

fsync(2) 联机帮助页告诉如果同步文件,则明确需要同步目录。

io包中Java的sync方法怎么样?是在意那个吗?它是否取决于操作系统和/或文件系统?

我在http://docs.oracle.com/javase/7/docs/api/java/io/FileDescriptor.html#sync 中发现没有任何帮助...

java linux synchronization fsync

5
推荐指数
1
解决办法
378
查看次数

fsync(fd)是否适用于外部程序创建的文件?

我有一个禁用写入缓存的SATA硬盘:

hdparm -W0 /dev/foo
Run Code Online (Sandbox Code Playgroud)

我正在ext4使用这些挂载选项(以及其他)的分区上运行:

data=ordered
auto_da_alloc
Run Code Online (Sandbox Code Playgroud)

Linux内核版本是2.6.32-5-686.

现在,我有一个我无法修改的外部程序,但我知道以下列方式创建一个文件:

int fd = open(path);
write(fd, data, data_size);
close(fd);
Run Code Online (Sandbox Code Playgroud)

即它在关闭之前不会fsync.所以在这一点上,数据可能在RAM中,在kernel/fs缓存中的某个地方.

注意:元数据还不是一个问题:我确保数据已经到达磁盘盘片之后,最终的元数据将被写入并保存.数据本身就是问题所在.

所以问题是,我如何帮助数据到达实际的磁盘盘片?

我之后想过运行这个单独的程序:

int fd = open(path);
fsync(fd);
close(fd);
Run Code Online (Sandbox Code Playgroud)

这有助于刷新数据,还是应该使用不同的方法?

linux fsync sata ext4

5
推荐指数
1
解决办法
246
查看次数

替代Windows c ++的Fsync

是否有替代Windows的fsync?(C++ builder)

Fsync需要包含unistd.h,它仅适用于unix系统

谢谢!

c++ windows fsync

5
推荐指数
2
解决办法
4238
查看次数

如何在 Linux 中使用 C 原子和异步地编写文件

如何在不需要我的程序等待慢速物理媒体(例如 with fsync)的情况下自动更新文件?

我希望操作系统可以在 RAM 中“缓冲”典型fsyncrename操作,然后方便时以正确的顺序将它们写入磁盘。


背景

我正在开发在带有ext4文件系统的自定义嵌入式 Linux 环境中运行的软件。该程序定期更新磁盘上的文件。我需要在不牺牲应用程序性能的情况下保持该文件的完整性。

根据我的阅读安全更新文件的公认做法如下:

  1. 创建一个新的临时文件
  2. 将数据写入临时文件
  3. fsync() 临时文件
  4. 将临时文件重命名为适当的名称
  5. fsync() 包含目录

这个过程对我来说很有意义,但在我的特定应用程序中,我想避免对fsync(). 我不在乎数据何时写入磁盘,只要文件始终处于有效状态即可。如果文件已过期,那没关系。


到目前为止我学到了什么

似乎已经有相当多的讨论ext4和正确使用fsync. 如果我理解正确,我可能可以放弃使用fsyncif auto_da_allocis enabled for my filesystem ( link ),但我不相信这是最好的解决方案。

c linux fsync embedded-linux ext4

5
推荐指数
1
解决办法
278
查看次数