如何在你自己的数据库管理系统中实现原子性输入输出?
解决方案
结论是我对磁盘实际工作方式的假设错了。我的新假设是:
- 写入是线性的。要么从第一个字节写到最后一个字节,要么反过来。当发生崩溃时,写入会在中途停止。
- 小于磁盘扇区大小的写入会让操作系统读取该扇区,修改其数据并写回。在硬件层面,读写都不会小于一个扇区。扇区至少为512字节(如今通常为4K)。
- 像
btrfs inspect-internal dump-super <path>这样的工具可以让你查看扇区大小。但你需要sudo权限。文件系统的实现各不相同且复杂,无法确切知道你这个文件内部的扇区边界在哪里,边界甚至可能分布不规律。 - CRC是检测写入是否在中途停止的一个好方法。
结论:你需要把元数据冗余存放在文件中的固定位置。你必须至少有两份完全相同的副本。覆盖时,先覆盖其中一个副本,将其force() 写入磁盘,然后再覆盖另一个副本。读取时,读取两份副本,要么两者相同,要么其中一个的CRC不正确。
这就是我能接受的方案。感谢大家,尤其是 @Slaw的帮助。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。