我意外地向两个 ext4 文件系统之间的某些文件启动了 32 个进程(虚拟机上每个核心一个进程)mv
,但只有其中一些成功mv
:
for i in `seq 1 32`; do
mv /path/to/ext4-1/pattern* /path/to/ext4-2/ &
done
当多个进程尝试 mv 相同的文件时到底会发生什么?
答案1
mv
在同一文件系统内对于每个文件来说都是原子的,但在文件系统中,这是一个更加复杂的操作(假设您只移动常规文件并且目的地最初不存在):
- 删除目标文件(如果存在)。
- 打开源文件进行阅读。某些实现可能会在上一步之前执行此操作。
- 创建目标文件。如果此时存在,某些实现可能会截断它。某些实现可能会在上一步之前执行此操作。
- 从源文件中读取一些数据并将其写入目标文件。
- 将源文件的元数据复制到目标文件上。某些实现可能会在下一步之后执行部分或全部操作。
- 关闭源文件和目标文件。
- 删除源文件。
在大多数情况下,如果两个mv
进程尝试同时移动同一个文件,它们都会复制数据:第一个启动的实例将创建一个文件,第二个实例将删除该文件并创建一个新文件。然而,如果运气不好,可能会丢失数据。例如:
- 实例 1 执行复制并关闭两个文件(步骤 1-6)。
- 此时,实例 2 到达此文件并删除目标(步骤 1),但在打开源文件之前被抢占。
- 实例 1 继续删除源文件(步骤 7)。
- 实例 2 继续执行步骤 2,但该文件不再存在。
我认为如果文件存在于目的地,它将具有正确的内容。但正如我们所见,文件有可能消失。