перепишите существующий файл так, чтобы он был заменен новой версией атомарно, только когда-то полностью записанный

Мир шел дальше. Автоинструменты и поставщики программного блока дистрибутива согласовывают различия в библиотеках и интерфейсах и корректируются по мере необходимости.

18
11.11.2011, 13:36
3 ответа

Это напоминает мне о, Выделяют На Сбросе. Когда файловая система использует эту функцию, вместо того, чтобы писать данные непосредственно в диск, это вычитает размер данных, которые будут записаны из счетчика свободного пространства диска и содержит данные в памяти до него, синхронизирующий системный вызов выполняется, или ядро решает сбросить грязные буферы.

В этом случае, если файл будет изменен одним процессом и будет открыт другим процессом, то последний процесс будет "видеть" неизмененный (или "старый", если Вы предпочтете), версия файла.

Конечно, вышеупомянутое являются теоретическими и зависят от различных факторов, и я сказал бы немного непредсказуемый - так как Вы не знаете точно, когда ядро идет, сбрасывают грязные страницы. Например, в Linux (поскольку можно также считать в разделе 15.3 из Понимания Ядра Linux), грязные страницы записаны в диск при следующих условиях:

  • Кэш страницы становится слишком полным, и необходимо больше страниц, или количество грязных страниц становится слишком большим.

  • Слишком много времени протекло, так как страница осталась грязной.

  • Процесс запрашивает все незаконченные изменения блочного устройства или конкретного файла быть сброшенными; это делает это путем вызова синхронизации (), fsync (), или fdatasync () системный вызов.

Эта опция, как известно, реализована в HFS +, XFS, Reiser4, ZFS, Btrfs и ext4 файловые системы.

1
27.01.2020, 19:46
  • 1
    То, что Вы описываете, является методом файловой системы, который должен быть невидимым от пространства пользователя (и таким образом не делает то, на что Вы указываете) на POSIX (файл) системы (см. запись: "Если чтение () данных файла, как могут доказывать, (каким-либо образом) происходит после записи () данных, это должно отразить, что запись (), даже если вызовы выполняются различными процессами".). Другие процессы не будут видеть старые данные (на POSIX). –  Mat 29.11.2011, 15:03
  • 2
    Спасибо за исправление. Я предполагаю, что мое понимание этого метода файловой системы было неправильным. –  dkaragasidis 29.11.2011, 16:45
  • 3
    Право, это похоже на что-то еще. Я неопределенно вспоминаю теперь, когда это было в интервью с RMS, что он упомянул эту функцию, возможно, это была некоторая старая тайная система, которая никогда не жила за пределами академии... Спасибо так или иначе. –  eudoxos 29.11.2011, 19:33

То, что Вы описываете, точно кажется, что основное переименовывает для перезаписи файла.

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

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

14
27.01.2020, 19:46
  • 1
    Только можно использовать это, если программа конкретно записана с функциональностью в памяти. В этом случае, однако, это была функция OS, откуда даже обычным программам дали эту атомную семантику автоматически. –  eudoxos 29.03.2012, 11:05
  • 2
    @eudoxos Ваш комментарий не имеет никакого смысла. Вы говорите, что программы должны были бы быть записаны конкретно, чтобы сделать rename вещь подкачки. Даже если такая 'функция OS', поскольку Вы говорите о существовавшем, программа, должна была бы все еще быть записана для использования в своих интересах этого также. Каково различие? –  Patrick 29.03.2012, 14:39
  • 3
    Существует различие, если Вы передаете (возможно неподдерживаемый) флаг к open syscall или если необходимо сделать то, что Вы описываете вручную. $ –  eudoxos 30.03.2012, 14:10
  • 4
    Следует иметь в виду, что для хранения или старое или полностью записанная новая версия в случае катастрофического отказа необходимо дополнительно синхронизировать новый файл к диску с fsync или подобный –  textshell 24.07.2016, 21:41
  • 5
    @textshell без синхронизации, Вы все еще получаете атомарность, хотя.... просто не длительность... исправляют? Я не понимаю аргумент в goo.gl/qfQQfy в этом случае. В моем случае у меня есть система под экстремальной нагрузкой, и я хочу избежать сбросов файловой системы, и я не забочусь, переживает ли файл катастрофический отказ. –  wcochran 29.11.2017, 18:52

Как Patrick пишет, обычный способ сделать, это должно записать новую версию в отдельный файл и по окончании переименовать новую версию к старому имени файла, перезаписав его атомарно. Эту вторую операцию называют overwrite-rename.

Теперь, некоторые ссылки:

6
27.01.2020, 19:46
  • 1
    man 3p rename говорит мне это rename является действительно атомарным, и я предполагаю, что это предназначено для всех файловых систем Linux. И когда я прочитал первую статью, которую Вы связали, я все еще думаю, что Btrfs переименовывают операции, являются атомарными. ответ Read Fiximan –  hagello 27.07.2015, 15:17

Теги

Похожие вопросы