C++ 仅刷新文件元数据

C++ 仅刷新文件元数据,c++,file,winapi,unix,linux-kernel,C++,File,Winapi,Unix,Linux Kernel,我们正在开发一个新的ACID数据库系统,它更关注数据完整性而不是吞吐量。它的存储引擎通过O\u DIRECT或FILE\u FLAG\u WRITE\u等标志直接访问辅助存储设备和FILE\u FLAG\u NO\u BUFFERING 在某些情况下,我们只使用内核函数更改文件元数据,如fallocate()或SetFileValidData()-在这些情况下,我只希望刷新元数据,而不是所有挂起的文件I/O,以利用调用阻塞时的执行性能,直到设备报告传输已完成-即使未使用任何文件缓冲,它仍然仅适用

我们正在开发一个新的ACID数据库系统,它更关注数据完整性而不是吞吐量。它的存储引擎通过
O\u DIRECT
FILE\u FLAG\u WRITE\u等标志直接访问辅助存储设备
FILE\u FLAG\u NO\u BUFFERING

在某些情况下,我们只使用内核函数更改文件元数据,如
fallocate()
SetFileValidData()
-在这些情况下,我只希望刷新元数据,而不是所有挂起的文件I/O,以利用调用阻塞时的执行性能,直到设备报告传输已完成-即使未使用任何文件缓冲,它仍然仅适用于应用程序数据,文件系统仍可能缓存文件元数据


到目前为止,我发现
fsync()
FlushFileBuffers()
刷新元数据,但不幸的是,它也会刷新所有挂起的I/O。有人知道只刷新文件元数据的方法吗?此问题适用于Linux、UNIX和Windows

我是FS的新手。但当您完成任何物理FS(ext4/ext3/etc)的实现时,它们并没有向上层公开这样的功能。但在fsyc()实现的内部,它们只更新文件的元数据,其余任务被委托给generic_block_fdatasync()。 您可能需要编写一个hack来满足只刷新元数据的需求

有人知道只刷新文件元数据的方法吗

,据我了解,任何操作系统都不提供接口/API。文件系统提供了两种类型的接口,应用程序(用户模式)程序可以通过这两种接口控制数据写入/保存到磁盘的时间

fsync:对fsync()的调用确保与文件描述符fd映射的文件相关联的所有脏数据被写回磁盘。此调用同时回写数据和元数据

fdatasync:此系统调用执行与fsync()相同的操作,只是它只刷新数据

这意味着有一种方法可以执行与此问题中提到的任务相反的任务。然而,在阅读您的问题时,我觉得您希望实现这一点,以获得最佳性能和数据一致性。根据我的理解,我们不应该过多地考虑执行性能,因为现代的文件系统实现了的“延迟写入”和各种其他机制,以避免不必要的磁盘写入

这里的主要目的是在用户模式和内核模式之间切换,因为这比其他任何模式都要昂贵。这可能是内核开发人员没有提供这样的接口的原因,该接口只能用于更新该特定文件的元数据。这可能是由于文件系统的局限性造成的,我想在这里我们几乎无法实现更高的效率


有关内部算法的完整信息,请参阅Maurice J Bach的经典著作《UNIX操作系统的设计》
,该书详细描述了这些概念和实现。

元数据是什么意思?这是文件名、大小和访问日期,还是文件内容的某一部分?正如OP中提到的,我们的数据库系统必须是完全酸性的,因此我们关闭了文件系统和操作系统缓存(或您所称的“延迟写入”)在UNIX/Linux上使用像
O\u DIRECT
这样的标志,在Windows上使用
FILE\u FLAG\u WRITE\u THROUGH
FILE\u FLAG\u NO\u BUFFERING
这样的标志。我们的主要目的不是上下文切换(如您所设想的),而是数据完整性和持久性。顺便说一句,我能够通过关闭()文件并重新打开它来完成我想要的。是的,看来黑客攻击是唯一的方法——与您的本地内核向导交谈。