内存映射文件和单个块的原子写入

Mar*_*bst 13 mmap acid atomic fwrite

如果我使用普通IO API读取和写入单个文件,则保证写入是基于每个块的原子.也就是说,如果我的write只修改了一个块,那么操作系统会保证写入整个块,或者根本不写入.

如何在内存映射文件上实现相同的效果?

内存映射文件只是字节数组,所以如果我修改字节数组,操作系统无法知道何时我认为写"完成",所以它可能(即使不太可能)在内存中交换内存我的块写操作的中间,实际上我写了半个块.

我需要某种形式的"进入/离开临界区",或"钉住"文件的页面到内存中,而我写它的一些方法.这样的事情存在吗?如果是这样,那可移植到常见的POSIX系统和Windows吗?

Jus*_*tin 5

保持期刊的技术似乎是唯一的方法.我不知道这对于写入同一文件的多个应用程序是如何工作的.Cassandra项目有一篇关于如何通过期刊获得表现的好文章.关键是要确保,日志只记录积极行动(我的第一种方法是将每个写入的前映像写入日志,允许您回滚,但它过于复杂).

所以基本上你的内存映射文件transactionId在标题中有一个,如果你的标题适合一个块,你知道它不会被破坏,尽管很多人似乎用校验和写了两次:[header[cksum]] [header[cksum]].如果第一个校验和失败,请使用第二个.

期刊看起来像这样:

[beginTxn[txnid]] [offset, length, data...] [commitTxn[txnid]]
Run Code Online (Sandbox Code Playgroud)

您只需继续附加日志记录,直到它变得太大,然后在某些时候将其翻转.启动程序时,检查文件的事务ID是否在日志的最后一个事务ID中 - 如果不是,则回放日志中的所有事务以进行同步.