同步太快

Fsync too fast?

本文关键字:同步      更新时间:2023-10-16

我对大文件ftruncatefsync操作感到惊讶。我写了一个程序,在 Linux 64 位系统上创建一个空文件,将其截断为 0xffffffff 字节,然后fsync它。

完成所有操作后,将正确创建具有此长度的文件。

我看到ftruncate花费大约 1442 微秒,fsync成本仅为 4 微秒。

正常是这么高的性能吗?光盘上的所有字节真的都烂了吗?如果没有,我该如何确保此同步?

#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
static const size_t __tamFile__ = 0xffffffff;
int main(int, char **)
{
    std::string fichero("./testTruncate.dat");
    unlink(fichero.c_str());
    int fd = open(fichero.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    if (fd != -1)
    {
        struct timeval t1, t2;
        timerclear(&t1);
        timerclear(&t2);
        gettimeofday(&t1, NULL);
        ftruncate(fd, __tamFile__);
        gettimeofday(&t2, NULL);
        unsigned long long msecTruncate = static_cast<unsigned long long>((((t2.tv_sec * 1E6) + t2.tv_usec) - ((t1.tv_sec * 1E6) + t1.tv_usec))) ;
        gettimeofday(&t1, NULL);
        fdatasync(fd);
        gettimeofday(&t2, NULL);
        unsigned long long msecFsync = static_cast<unsigned long long>((((t2.tv_sec * 1E6) + t2.tv_usec) - ((t1.tv_sec * 1E6) + t1.tv_usec))) ;
        std::cout << "Total microsec truncate: " << msecTruncate << std::endl;
        std::cout << "Total microsec fsync: " << msecFsync << std::endl;
        close(fd);
    }
    return 0;
}

我写了一个程序,在 Linux 64 位系统上创建一个空文件, 将其截断为 0xffffffff 个字节,然后进行同步。

除非你写了一些东西,否则文件极有可能包含漏洞。

来自TLPI:

如果程序查找超过文件末尾,然后 执行 I/O?调用 read() 将返回 0,表示文件结束。 有点令人惊讶的是,可以任意写入字节 指向文件末尾。

前一端之间的空格 的文件和新写入的字节称为文件孔。 从编程的角度来看,孔中的字节是存在的,并且 从孔读取返回包含 0 (空 字节)。

但是,文件孔不会占用任何磁盘空间。该文件 系统不会为孔分配任何磁盘块,直到在某些 稍后,数据被写入其中。

您拥有哪个 Linux 内核版本、哪个文件系统以及哪些挂载选项(特别是启用了屏障?

在 Linux 2.6.32 64 位、ext4 上启用了屏障(默认),我得到


$ ~/src/cpptest/truncsync 
Total microsec truncate: 32
Total microsec fsync: 266
Total microsec close: 14

否则相同,但是使用NFS挂载的文件系统,我得到


$ ./truncsync 
Total microsec truncate: 38297
Total microsec fsync: 6
Total microsec close: 6
$ ./truncsync 
Total microsec truncate: 3454967
Total microsec fsync: 8
Total microsec close: 330