使用mmap在文件中写入的原子性?

时间:2018-03-27 13:35:54

标签: c linux filesystems mmap

修改文件内容的一种方法是使用标记mmap运行MAP_SHARED,然后写入返回的内存区域。例如:

struct data *data;
const int size = sizeof(struct data);
int fd = open("data_file", O_RDWR);
ftruncate(fd, size);
data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
/* Access to 'data' members */

我们考虑使用日记文件系统(ext4data=ordereddata=journal)。我应该采取哪些预防措施才能在停电后从data_file恢复数据?

IMO,Linux保证写入操作将被订购但不保证任何原子性。因此,应用程序必须实现一种日志才能恢复data_file(正如大多数数据库所做的那样)。你确认了吗?

1 个答案:

答案 0 :(得分:1)

  

我应采取哪些预防措施才能在停电后从data_file恢复数据?

由于您无法保证mmap()内存更新的真正原子性,因此您需要做两件事:

  1. 使用互斥或​​其他同步机制来保护您的数据尽可能保持一致状态
  2. 使用msync()强制在更新后将数据写入磁盘。
  3. 请注意since you can't prevent mmap() data from being written to disk without an msync(),这很容易受到磁盘上数据的非原子更新的影响,但如果您的更新永远不会越过页面边界,则可以最大限度地降低风险。您必须在对象更新过程中出现故障,并且在交易过程中您必须让操作系统将该页面写入磁盘。

    如果您将互斥锁或其他同步对象放在mmap()数据本身中,我怀疑获取互斥锁的行为会导致mmap()' d会延迟任何数据写入的内存。将互斥锁置于数据本身可能会使恢复变得复杂,但只要您可以确保恢复是单线程的,如果不能完全忽略,那么解决这个问题应该不是很大的问题。

    此恢复问题的更好解决方案是不使用mmap()并以保证全有或全无更新的方式显式写入数据,但我怀疑这会对您的设计产生重大影响