Atomic пишет — как tempfile + os.replace предотвращает коррупцию JSON
Atomic writes — how tempfile + os.replace prevent corrupted JSON
Что произойдет, если питание отключится, пока процесс записывается в файл конфигурации? Или если антивирусное программное обеспечение на Windows ненадолго блокирует файл в середине записи? Если вы наивно перезаписываете файл с , какой бы частичный контент ни существовал в момент прерывания, это то, что остается на диске. Для JSON это обычно означает сломанный синтаксис — бросает на следующий стартап, и вся конфигурация фактически теряется. Эта статья проходит через стандартную технику предотвращения этого: сначала напишите временный файл, а затем поменяйте его атомарно. Примечание: «Атомная» здесь означает, что операция либо завершается полностью, либо не происходит вообще — нет частичного, наблюдаемого между состояниями. Это то же самое значение слова, используемого для операций с базами данных. Почему прямые перезаписи опасны, эффективно усечены.
Что произойдет, если питание отключится, пока процесс записывается в файл конфигурации? Или если антивирусное программное обеспечение на Windows ненадолго блокирует файл в середине записи? Если вы наивно перезаписываете файл с , какой бы частичный контент ни существовал в момент прерывания, это то, что остается на диске. Для JSON это обычно означает сломанный синтаксис — бросает на следующий стартап, и вся конфигурация фактически теряется. Эта статья проходит через стандартную технику предотвращения этого: сначала напишите временный файл, а затем поменяйте его атомарно. Примечание: «Атомная» здесь означает, что операция либо завершается полностью, либо не происходит вообще — нет частичного, наблюдаемого между состояниями. Это то же самое значение слова, используемого для операций с базами данных. Почему прямая перезапись опасна, сначала сокращает файл, а затем пишет новый контент. Если процесс прерывается во время этого окна, файл остается пустым или содержит неполное содержимое. Причины варьируются: отключение питания, антивирусное программное обеспечение, кратковременно блокирующее доступ к файлам в Windows, или инструмент резервного копирования, захватывающий файл в середине записи. Это редко воспроизводится во время локального развития, но в долгосрочной производственной среде это в конечном итоге произойдет с почти уверенностью. Исправление: напишите в временный файл, затем поменяйте его в основной идее. Никогда не касайтесь целевого файла напрямую. Сначала запишите полный новый контент во временный файл, подтвердите, что запись полностью удалась, и только затем замените целевой файл этим временным файлом. генерирует временное имя файла без столкновений и возвращает его дескриптор файла. Аргумент здесь имеет значение: размещение временного файла в том же каталоге, что и целевой файл, гарантирует, что следующий вызов остается в одной файловой системе. Почему атомная Ядром этой модели является окончательный вызов. Официальная документация Python гласит, что «будет атомной операцией на Unix» и ведёт себя атомарно на Windows, если оба пути находятся на одной файловой системе. В системах POSIX (Linux/macOS) эта карта отображает системный вызов. На уровне ядра замена записи каталога является единой неделимой операцией. Не существует промежуточного состояния для наблюдения — снаружи файл находится либо в состоянии перед свопом, либо в состоянии после своп, никогда между ними. В Windows Python 3.3+ реализует это так, что перезапись существующего файла обрабатывается атомарно (примерно эквивалентно вызову с флагом). Благодаря этому свойству, если процесс умирает в середине , затрагивается только неназванный временный файл — реальный файл конфигурации остается нетронутым в любом действительном состоянии, в котором он был раньше. Принуждение к постоянству на диске даже с атомарным , есть более тонкий риск: контент, написанный может все еще сидеть в кэше страницы ОС, а не физически на диске, когда мощность теряется. В этом случае само переименование может быть завершено, но содержимое переименованного файла может не отражать то, что было написано. Обратимся к этому. Это только подталкивает внутренний буфер Python к ОС — он все еще может находиться в кэше на уровне ОС. Он идет еще дальше и просит ОС подождать, пока данные будут записаны на физический диск. Объединение обоих этапов гарантирует, что содержимое временного файла будет постоянно находиться на диске к моменту запуска. Уборка после неудачного письма Если запись в сам временный файл не проходит частично (полный диск, ошибка разрешения и т. д.), никогда не достигается, поэтому целевой файл не затрагивается. Но наполовину написанный временный файл остается на диске. Оставленные без присмотра, они накапливаются как беспорядок, поэтому стоит удалить их явно при неудаче. Вложенная версия учитывает возможность того, что сама по себе не работает (уже удалена, нет разрешения и т. д.). Восстановление первоначального исключения () гарантирует, что абонент все еще узнает, что запись не удалась. Охрана от оставшихся файлов, поскольку потребляет временное имя файла и меняет его на целевое имя на успех, файлы обычно не задерживаются при обычной работе. Но в крайнем случае — процесс попадает в узкое окно сразу после того, как временный файл полностью написан