我一直在关注EXT4上的"bug",如果使用"创建临时文件,写入临时文件,将temp重命名为目标文件"进程,会导致文件在崩溃时归零.POSIX说,除非调用fsync(),否则您无法确定数据是否已刷新到硬盘.
显然这样做:
0) get the file contents (read it or make it somehow) 1) open original file and truncate it 2) write new contents 3) close file
即使使用fsync()也不好,因为计算机可能会在2)或fsync()期间崩溃,并且您最终会得到部分写入的文件.
通常认为这是非常安全的:
0) get the file contents (read it or make it somehow) 1) open temp file 2) write contents to temp file 3) close temp file 4) rename temp file to original file
不幸的是它不是.为了使其在EXT4上安全,您需要执行以下操作:
0) get the file contents (read it or make it somehow) 1) open temp file 2) write contents to temp file 3) fsync() 4) close temp file 5) rename temp file to original file
这是安全的,在崩溃时你应该有新的文件内容或旧的,从不归零的内容或部分内容.但是如果应用程序使用大量文件,则每次写入后fsync()都会很慢.
所以我的问题是,如何在需要fsync()以确保更改已保存到磁盘的系统上有效地修改多个文件?我的意思是修改许多文件,就像成千上万的文件一样.修改两个文件并在每个文件之后执行fsync()不会太糟糕,但fsync()在修改多个文件时确实会减慢速度.
编辑:将fsync()关闭临时文件更改为正确的顺序,强调编写许多文件.