Если вы хотите быть POSIXly правильным и сохранить, вы должны:
- Запись во временный файл
- Сброс и
fsync
файл (или fdatasync
)
- Переименовать поверх исходного файла
Обратите внимание, что вызов fsync оказывает непредсказуемое влияние на производительность - в результате Linux на ext3 может зависать от целого числа секунд дискового ввода-вывода, в зависимости от других ожидающих операций ввода-вывода.
Обратите внимание, что rename
является , а не атомарной операцией в POSIX - по крайней мере, не по отношению к данным файла, как вы ожидаете. Однако большинство операционных систем и файловых систем будут работать таким образом. Но, похоже, вы пропустили очень большую дискуссию по Linux о Ext4 и гарантиях файловой системы на атомарность. Я не знаю точно, где ссылаться, но вот начало: ext4 и потеря данных .
Обратите внимание, что во многих системах переименование будет на практике настолько безопасным, насколько вы ожидаете. Тем не менее, невозможно достичь ни производительности, ни надежности во всех возможных конфигурациях Linux!
При записи во временный файл, а затем переименовании временного файла можно ожидать, что операции являются зависимыми и будут выполняться по порядку.
Однако проблема в том, что большинство, если не все файловые системы разделяют метаданные и данные. Переименование - это только метаданные. Это может показаться вам ужасным, но файловые системы ценят метаданные по сравнению с данными (например, ведение журнала в HFS + или Ext3,4)! Причина в том, что метаданные легче, и если метаданные повреждены, вся файловая система повреждена - файловая система должна, конечно, сохранить себя, а затем сохранить данные пользователя в этом порядке.
Ext4 действительно сломал ожидание rename
, когда оно только появилось, однако для его устранения были добавлены эвристики. Проблема в не неудачном переименовании, а в успешном переименовании. Ext4 может успешно зарегистрировать переименование, но не сможет записать данные файла, если вскоре произойдет сбой. В результате получается файл нулевой длины, в котором нет ни оригинальных, ни новых данных.
Короче говоря, POSIX не дает такой гарантии. Прочитайте связанную статью Ext4 для получения дополнительной информации!