Многие распространенные файловые системы не предлагают элементарных операций, однако в некоторых сценариях очень важна запись файлов атомарным способом.Я попытался найти решение этой проблемы.
Я сделал следующие предположения:
- Используемая файловая система поддерживает атомарные операции на уровне inode (например, NTFS).Это означает, что move и delete являются атомарными.
- Доступ к файлам имеет только сама программа.
- В программе имеется только 1 экземпляр программы.время, и он действует однопоточным образом.
- Для простоты каждый раз записывается содержимое всего файла (т. е. усеченная запись).
Это оставляет следующую проблему: При записи файла программа может быть прервана, и в файле останется только часть содержимого для записи.
Я предлагаю следующий процесс:
- Запись новогосодержимое во временный файл Новый
- Перемещение исходного файла Оригинал во временное расположение Резервное копирование
- Перемещение Новый до Оригинал
- Удалить Резервное копирование
Новое и Резервное копирование файлы отличаются от оригинальных файлов (например, они могут иметь префикс по-разному или могут быть разделеныкаталог на том же томе).В то же время их имя должно отображаться непосредственно в соответствующий Оригинал (например, просто с помощью того же имени файла).
Это, однако, еще не делает операцию атомарной.Процесс может быть прерван шагами 1, 2, 3 или 4:
- Оставляет потенциально незавершенным Новый .
- Перемещение является атомарным, но целевой файлсейчас отсутствует.Обе Новые и Резервная копия существуют и завершены.
- Перемещение является атомарным, но есть неиспользованная Резервная копия . Оригинал был заменен на Новый контент
- Удаление является атомарным.
Используя предположения 2 и 3, ранее, программа имеетбыть перезапущен после аварии.В процессе запуска он должен выполнить следующие проверки восстановления:
- Если Новый существует, но Резервная копия нет, мы потерпели крах в или после шага 1. Удалить Новый , поскольку он может быть неполным.
- Если существует Новый и существует Резервная копия , мы потерпели крах после шага 2. Перейдите к шагу 3.
- Если Резервное копирование существует, но Новое тоже не произошло, то мы потерпели крах после шага 3. Продолжите с шага 4.
Восстановлениесам процесс, использующий только атомарные операции, просто продолжит с того места, на котором остановился после прерывания.
Я считаю, что эта идея обеспечивает атомарную запись для одной программы.Эти проблемы все еще существуют:
- При использовании нескольких экземпляров одной и той же программы в процессе восстановления возникают помехи для текущих записей файлов в другой программе.
- За пределами программ, которыетолько чтение, но никогда не запись обычно дает правильный результат, но если в запрошенную запись одновременно выполняется операция записи, они могут неправильно найти запись.
Те проблемы (которые исключены)с помощью предположений ранее) может быть решена с помощью политики использования (например, проверка на наличие других экземпляров и запрет на доступ к каталогу для других пользователей).
Наконец, мой вопрос: имеет ли это смысл или есть недостатокв процессе?Существуют ли какие-либо проблемы, препятствующие использованию этого подхода на практике?