未在BTRFS关闭的文件和旧版本重新出现

时间:2017-03-24 17:23:36

标签: java java-8 centos7 btrfs

经过大量测试和挖掘BTRFS手册之后,我需要一些Linux / BTRFS人员的帮助。

我有一个java应用程序,它使用java MappedByteBuffer实用程序将数据文件写入磁盘。这是应用程序在写入磁盘时使用~16000字节的字节缓冲区。当正在向其写入新文件时,会创建缓冲区大小的临时文件,并且由于mem-mapped文件的java实现,代码不会显式关闭该文件。相反,我们调用Linux的drop_caches来强制未使用的内存映射刷新到磁盘。

  • 在EXT4上,这些文件会自动关闭,文件大小也会正确调整。
  • 在BTRFS上,这些文件保留~16000字节,并且缺少一些数据(可能是分页问题)
  • 在BTRFS上,当我删除这些文件并且软件重新运行并再次创建文件时,每次都会出现同样的问题,并且修改日期是从最初创建文件时开始的。

服务器信息: 我们正在运行最新的centos 7.2并且是最新的补丁

  • OS Centos 7 x64(内核3.10.0-514.10.2.el7.x86_64)
  • btrfs-progs v4.4.1
  • Java 1.8.0_111

已执行测试

  • 我们在Ext4上运行了一个副本服务器,但这个问题没有发生

  • 我们目前正在使用COW和压缩,因此我尝试禁用它们,重新启动,删除旧数据并重新启动软件。问题仍然存在

  • 我也试过禁用space_cache,恢复,我也尝试使用flushoncommit设置commit = 5 ...这也没有帮助非关闭文件/错误的修改日期

1 个答案:

答案 0 :(得分:1)

  

由于mem-mapped文件的java实现,代码没有显式关闭文件。

这没有多大意义。文件支持的内存映射不要求其文件描述符保持打开状态。所以你绝对可以在创建映射缓冲区后关闭文件。

  

相反,我们调用Linux的drop_caches来强制未使用的内存映射刷新到磁盘。

这是大规模的矫枉过正。

  1. 使用MappedByteBuffer::force将更改同步到磁盘
  2. 重命名tempfile
  3. 为崩溃持久性重命名后fsync所需的目录(参见下面的参考资料)。

  4. try(FileChannel dir = FileChannel.open(Paths.get("/path/directory"), StandardOpenOptions.READ)) {
      dir.force(true);
    }