Назад | Перейти на главную страницу

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/folder2. Для файла размером 1 ГБ требуется примерно 10 секунд:

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

А также производит высокую дисковую активность. Однако, когда я перемещаю один и тот же файл между /drive2/folder1 и /drive2/folder2, его перемещение занимает меньше секунды.

Кто-нибудь может сообщить мне об этой проблеме?

При перемещении между файловыми системами файл копируется в место назначения, а затем удаляется в источнике. При перемещении по локальной файловой системе обновляются только таблицы файловой системы, что занимает гораздо меньше времени. Очевидно, при монтировании привязки 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
......

oth folder1 и folder2 фактически находились в одной файловой системе, системный вызов переименования завершился неудачно, с сообщением об ошибке, что место назначения находится на отдельном устройстве. Не считая изменения ядра и / или основных библиотек, я сомневаюсь, что вы можете многое сделать, чтобы это изменить.

Я предполагаю, что вам нужно связать монтирование этих папок отдельно, потому что на / 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/