Что произойдет, если файл будет изменен во время копирования?

19

Каков эффект копирования файла, скажем, fileA.big (900mb) из местоположения B в местоположениеC. Если во время этой операции cp, скажем, через 35%, файл fileA.big будет дополнен новой информацией и увеличится с 900 до 930 МБ.

Каков результат конечной копии (например, fileA.big в locationC)?

Что делать, если копия прошла примерно на 70%, а исходный файл обновлен, но на этот раз урезан до 400 МБ (т. Е. Ход копирования превышает точку усечения), каков результат конечной копии?

Обращение к ОС Linux в файловой системе ext3 / ext4. Никакой объемной магии теней и т. Д. Просто старый cp. Любопытство вызвано копированием живых файлов couchdb для резервного копирования, но больше интересует общие сценарии, а не конкретный вариант использования.

Мэтт Фрёман
источник
Спасибо, что спросили это. Мои «знания» были в основном предположением ... до сих пор.
Чепанг

Ответы:

10

Если fileA.bigон вырос во время копирования, копия будет содержать данные, которые были добавлены.

Если файл будет усечен короче, чем текущая копия, копия будет прервана в том месте, где она находится, а файл назначения будет содержать то, что было скопировано до момента ее прерывания.

Патрик
источник
27

У Патрика это более или менее правильно, но вот почему. Способ, которым вы копируете файл в UNIX, работает следующим образом:

  1. Попробуйте прочитать несколько (более) байтов из fileA.
  2. Если нам не удалось получить байты, потому что мы находимся (или прошли) конец файла, мы закончили; уволиться.
  3. В противном случае запишите байты в fileBи вернитесь к шагу 1.

Зная это, и зная, что это так просто, давайте рассмотрим некоторые угловые случаи.

Как только мы найдем конец файла, копия будет готова. Допустим, наш файл увеличивается во время копирования, но растет медленнее, чем мы его копируем. Программа копирования будет продолжать превышать исходный размер файла, потому что к тому времени, когда он туда попадает, в файле появляется больше. Но в какой - то момент, он догоняет конец файла, и он знает , что это в конце , потому что он не может читать больше байтов прямо сейчас . Таким образом, он завершает работу, даже если файл будет расти дальше.

Если файл обрезан, программа копирования говорит: «Ух, конец файла!» и выходит.

И если части файла обновляются случайным образом, скажем, с помощью программы базы данных :-), то ваша копия будет представлять собой смесь старых и новых данных, потому что данные не все копируются одновременно. Результатом, вероятно, будет поврежденная копия, поэтому делать копии живых баз данных обычно не очень хорошая идея.

(Тем не менее, я не знаком с CouchDB, и возможно спроектировать базу данных так, чтобы она была устойчивой к такого рода коррупции. Но лучше быть абсолютно уверенным.)

Jander
источник
Хорошее объяснение. Кстати, меня всегда удивляло, почему это возможно в UNIX-подобных ОС без получения типичного сообщения об ошибке, известного из Windows («Не удается получить доступ к файлу - файл используется»). Вы даже не могли воспроизвести файл MP3, который уже был удален во время игры. Под Unix вы можете (на удивление) - без проблем вообще. Я предполагаю, что ОС на основе UNIX всегда работают с резервными копиями файлов, так что это возможно.
синтаксическая ошибка
1
На самом деле, возможность чтения удаленного файла происходит от другой функции UNIX: в UNIX файлы и имена файлов - это разные вещи. Когда вы удаляете файл, вы действительно удаляете именованную «ссылку» на файл. Когда программа открывает файл, это также считается ссылкой. Система удалит сам файл только тогда, когда на него не осталось ссылок.
январь
Так что, если файл растет быстрее, чем мы можем скопировать, cp никогда не прекратит работу? Я понимаю, что это маловероятно, так как все записи в файл должны были бы иметь возможность записи в файл быстрее, чем CP может прочитать из него.
Блад