修改文件内容的一种方法是使用标记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 */
我们考虑使用日记文件系统(ext4
与data=ordered
或data=journal
)。我应该采取哪些预防措施才能在停电后从data_file
恢复数据?
IMO,Linux保证写入操作将被订购但不保证任何原子性。因此,应用程序必须实现一种日志才能恢复data_file
(正如大多数数据库所做的那样)。你确认了吗?
答案 0 :(得分:1)
我应采取哪些预防措施才能在停电后从
data_file
恢复数据?
由于您无法保证mmap()
内存更新的真正原子性,因此您需要做两件事:
msync()
强制在更新后将数据写入磁盘。请注意since you can't prevent mmap()
data from being written to disk without an msync()
,这很容易受到磁盘上数据的非原子更新的影响,但如果您的更新永远不会越过页面边界,则可以最大限度地降低风险。您必须在对象更新过程中出现故障,并且在交易过程中您必须让操作系统将该页面写入磁盘。
如果您将互斥锁或其他同步对象放在mmap()
数据本身中,我怀疑获取互斥锁的行为会导致mmap()
' d会延迟任何数据写入的内存。将互斥锁置于数据本身可能会使恢复变得复杂,但只要您可以确保恢复是单线程的,如果不能完全忽略,那么解决这个问题应该不是很大的问题。
此恢复问题的更好解决方案是不使用mmap()
并以保证全有或全无更新的方式显式写入数据,但我怀疑这会对您的设计产生重大影响