Почему запись в существующий файл в Windows так подвержена потере данных при сбое питания, даже после закрытия файла? - PullRequest
2 голосов
/ 24 октября 2019

Я использую robocopy для зеркального отображения каталога по сети на машине. Машина назначения подвержена потере мощности. Несколько раз я обнаруживал, что после успешной робокопии некоторые файлы имеют правильный размер / дату, но они пусты (все байты NUL).

Robocopy копирует файл с помощью

  1. Создание файла в месте назначения
  2. Установка времени его мода на эпоху
  3. Установка размера файла
  4. Запись реальных байтов в файл
  5. Установка времени модификации / создания в соответствии с исходным кодом

Таким образом, я получил файлы, которые действовали как 1-3 и 5, но 4 - нет. Robocopy использует даты модификации, чтобы решить, какие файлы обновлять, поэтому файлы, «поврежденные» из-за потери питания во время robocopy, не будут исправлены при более позднем успешном запуске robocopy.

Заинтригованный, я повторил это поведение в большом масштабебез робокопии. Выполнение этого кода Python и включение питания после примерно 30000 файлов дает интересные результаты:

for i in range(100000):
    if i and i%1000 == 0:
        print(i)
    with open(str(i),'wb') as f:
        f.truncate(5)
    with open(str(i),'r+') as f:
        f.write('ccccc')

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

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

Такое поведение делает робокопию довольно бесполезной в сценариях с отключением питания. Даже потеря мощности вскоре после полного завершения робокопии может привести к потере.

...