mount --bind 并在挂载点之间移动 2 个文件

mount --bind 并在挂载点之间移动 2 个文件

我的应用程序架构要求我在同一分区挂载 2 个文件夹并在它们之间移动 2 个文件。我有以下挂载:

/drive2/folder1 on /var/www/myapp/folder1 type none (rw,bind)
/drive2/folder2 on /var/www/myapp/folder2 type none (rw,bind)

问题在于在 2 个文件夹之间移动文件/var/www/myapp/folder1/var/www/myapp/folder21Gb 文件大约需要 10 秒:

mv /var/www/myapp/folder1/test /var/www/myapp/folder2/

而且它会产生大量磁盘活动。但是,当我在/drive2/folder1和之间移动同一个文件时/drive2/folder2,移动它只需不到一秒钟的时间。

有人能帮我解决这个问题吗?

答案1

在文件系统之间移动时,文件会被复制到目标,然后在源上删除。在本地文件系统上移动时,只会更新文件系统表,这需要的时间要少得多。显然,使用绑定挂载,mv 会将这两个点视为单独的文件系统。

我在本地系统上设置了类似的挂载并运行strace mv folder1/1gb folder2/

lstat("folder1/1gb", {st_mode=S_IFREG|0644, st_size=1000000000, ...}) = 0
lstat("folder2/1gb", 0x7fff30fd1e20)    = -1 ENOENT (No such file or directory)
rename("folder1/1gb", "folder2/1gb")    = -1 EXDEV (Invalid cross-device link)
unlink("folder2/1gb")                   = -1 ENOENT (No such file or directory)
open("folder1/1gb", O_RDONLY|O_NOFOLLOW) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=1000000000, ...}) = 0
open("folder2/1gb", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 32768) = 32768
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 32768) = 32768
......

由于文件夹 1 和文件夹 2 实际上位于同一文件系统上,因此重命名系统调用失败,并报告错误,指出目标位于单独的设备上。除了修改内核和/或核心库之外,我怀疑您无法做太多事情来改变这种情况。

答案2

我假设您需要单独绑定安装这些文件夹,因为 /drive2 上还有其他文件夹,并且您的应用程序由于使用了类似 chroot 的东西而无法使用符号链接。

如果您可以在 /drive2 和 folder1 及 folder2 之间添加另一个目录,则可以实现相同的目的,而不会影响性能。然后,您只需要绑定挂载该文件夹。

 $ ls /drive2/myapp
 folder1         folder2

然后你的绑定挂载将是

 /drive2/myapp on /var/www/myapp/myapp type none (rw,bind)

现在你的动作将再次即时

mv /var/www/myapp/myapp/folder1/test /var/www/myapp/myapp/folder2/

相关内容