【问题标题】:Writing to a files raw disk sectors写入文件原始磁盘扇区
【发布时间】:2012-09-02 03:36:31
【问题描述】:

我正在使用 OS 便携式数据库服务器,我想知道在不锁定整个文件的情况下读取/写入索引文件磁盘扇区的最佳方法是什么。我的数据库磁盘管理器有一个位图,用于跟踪索引文件中所有已使用/未使用的扇区的位置。另外,是否有操作系统可移植的方式来执行此操作?

【问题讨论】:

  • 您无需了解任何有关原始磁盘扇区的信息即可执行此操作。只需使用控制搜索或 I/O 偏移的函数即可。例如fseekftell.
  • 这就是司机的目的,只有司机知道这么低的细节
  • @BenVoigt 当我使用 fseek 和 ftell 时,多个线程可以同时写入同一个文件吗?
  • 如果您想要可预测的结果,线程不能同时写入文件中的同一位置。例如,如果文件中有“A”,则一个线程会同时写入“B”和另一个“C”——无法知道最终的结果是“B”还是“C”
  • @Drakosha 我的磁盘管理器确保两个线程不会同时写入同一个扇区。

标签: c++ c database


【解决方案1】:

...在不锁定整个文件的情况下读取/写入索引文件磁盘扇区。

您可以只锁定您正在写入的(文件的)部分。在 Windows 下,这将使用LockFile 完成。顺便说一句,为什么不锁定整个文件很重要?无论如何,您的服务器将拥有对它的独占访问权限,并且它可以在内部管理锁定(除非您想要一个无服务器/嵌入式数据库,同时仍允许多个客户端连接到它)。

要实现事务durability,您还需要确保您写入的数据不会停留在缓存/缓冲区中,并且在正确的时间物理写入磁盘。在 Windows 下,考虑将 FILE_FLAG_WRITE_THROUGH(可能还有 FILE_FLAG_NO_BUFFERING,假设您自己进行缓存管理)传递给 CreateFile

我不认为有任何独立于操作系统的 API 用于这些 - 您需要在每个支持的操作系统下以特殊方式执行此操作。当然,没有什么能阻止您封装特定于操作系统的代码并向系统的其余部分提供统一的接口。

【讨论】:

  • lockffflush 不是独立于操作系统的 API 吗?
  • @BenVoigt:我不确定lockf 是否可以在 Windows 上使用。 fflush 不够持久:在某些系统上甚至 fsync 都不够,您可能需要fcntl(F_FULLSYNC)
  • 我怀疑 CreateFile 是在 WinOS 上解决这个问题的方法。感谢您的耐用性提示,以前从未读过。由于一次只有一个进程会访问该文件,因此我想在磁盘管理器位图中实现锁定,但稍后我会记住 LockFile。
  • 我可以确认至少在 WinOS 上要走的路是 CreateFileWriteFileReadFileSetFilePointer。为了持久性,请使用 FILE_FLAG_WRITE_THROUGHFILE_FLAG_NO_BUFFERING 或使用 fflush 手动刷新磁盘文件缓存。
猜你喜欢
  • 2019-12-05
  • 2014-04-30
  • 2013-10-05
  • 2011-08-22
  • 2014-10-24
  • 2012-11-27
  • 1970-01-01
  • 2020-02-03
  • 2017-06-17
相关资源
最近更新 更多