如果我使用普通 IO API 读取和写入单个文件,则保证每个块的写入都是原子的。也就是说,如果我的写入仅修改单个块,则操作系统保证要么写入整个块,要么什么也不写入。
如何在内存映射文件上达到相同的效果?
内存映射文件只是字节数组,因此如果我修改字节数组,操作系统无法知道我何时考虑写入“完成”,因此它可能(即使不太可能)交换出内存中的内存在我的块写入操作的中间,实际上我写了半个块。
我需要某种“进入/离开关键部分”,或者在写入文件时将文件页面“固定”到内存中的某种方法。存在这样的东西吗?如果是这样,它可以在常见的 POSIX 系统和 Windows 之间移植吗?
保持一个的技术journal http://onjava.com/pub/a/onjava/2002/02/06/atomic.html似乎是唯一的办法。我不知道这对于多个应用程序写入同一文件是如何工作的。 Cassandra 项目有一个好文章 http://wiki.apache.org/cassandra/Durability关于如何通过日记获得绩效。关键是要确保日志只记录positive动作(我的第一个方法是将每次写入的原像写入日志,允许您回滚,但它变得过于复杂)。
所以基本上你的内存映射文件有一个transactionId
在标头中,如果您的标头适合一个块,您就知道它不会被损坏,尽管许多人似乎用校验和将其写入两次:[header[cksum]] [header[cksum]]
。如果第一个校验和失败,则使用第二个。
该日记看起来像这样:
[beginTxn[txnid]] [offset, length, data...] [commitTxn[txnid]]
您只需不断附加日志记录,直到它变得太大,然后在某个时候将其滚动。当您启动程序时,您将检查文件的事务 ID 是否为日志的最后一个事务 ID,如果不是,您将回放日志中的所有事务以进行同步。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)