Мне нужно сделать запись в файл, но так, чтобы это было безопасно на случай непредвиденных сбоев
То есть есть, если в процессе записи в файл произойдет отключение питания — это не приведёт к потере данных
В Linux-e есть чудесный трюк: писать в другой файл, а затем переименовать его.
В Linux-e переименование — атомарная операция, а как быть в Windows?
( CreateFileTransacted не предлагать — нужно решение для XP )
Здравствуйте, Аноним, Вы писали:
А>Мне нужно сделать запись в файл, но так, чтобы это было безопасно на случай непредвиденных сбоев А>То есть есть, если в процессе записи в файл произойдет отключение питания — это не приведёт к потере данных А>В Linux-e есть чудесный трюк: писать в другой файл, а затем переименовать его. А>В Linux-e переименование — атомарная операция, а как быть в Windows? А>( CreateFileTransacted не предлагать — нужно решение для XP )
Здравствуйте, Аноним, Вы писали:
А>Мне нужно сделать запись в файл, но так, чтобы это было безопасно на случай непредвиденных сбоев
А такой вариант не устроит:
— пишем во временный файл
— проверяем целостность временного файла
— копируем временный файл в целевой
— проверяем целостность целевого, если все в порядке — удаляем временный
— при загрузке проверяем наличие временного файла, если находим — копируем в целевой, продолжая транзакцию как обычно.
Здравствуйте, jahr, Вы писали:
J>Здравствуйте, Аноним, Вы писали:
А>>Мне нужно сделать запись в файл, но так, чтобы это было безопасно на случай непредвиденных сбоев J>А такой вариант не устроит: J>- пишем во временный файл J>- проверяем целостность временного файла J>- копируем временный файл в целевой J>- проверяем целостность целевого, если все в порядке — удаляем временный J>- при загрузке проверяем наличие временного файла, если находим — копируем в целевой, продолжая транзакцию как обычно.
Можно проще:
1) Пишем во временный. (Надо добиться чтобы он был записан на диск, а не болтался в кэше).
2) Удаляем основной.
3) Переименовываем временный в основной.
При загрузке: если основного нет и есть временный, то (3). Если есть оба, то временный удаляем.
Re[3]: запись файла как транзакция
От:
Аноним
Дата:
04.05.11 13:57
Оценка:
Здравствуйте, andrey.desman, Вы писали:
AD>Здравствуйте, jahr, Вы писали:
J>>Здравствуйте, Аноним, Вы писали:
А>>>Мне нужно сделать запись в файл, но так, чтобы это было безопасно на случай непредвиденных сбоев J>>А такой вариант не устроит: J>>- пишем во временный файл J>>- проверяем целостность временного файла J>>- копируем временный файл в целевой J>>- проверяем целостность целевого, если все в порядке — удаляем временный J>>- при загрузке проверяем наличие временного файла, если находим — копируем в целевой, продолжая транзакцию как обычно.
AD>Можно проще: AD>1) Пишем во временный. (Надо добиться чтобы он был записан на диск, а не болтался в кэше). AD>2) Удаляем основной. AD>3) Переименовываем временный в основной.
AD>При загрузке: если основного нет и есть временный, то (3). Если есть оба, то временный удаляем.
проблема в переименовании. В Linux — это атомарная операция в в Windows — нет
Здравствуйте, Аноним, Вы писали:
А>проблема в переименовании. В Linux — это атомарная операция в в Windows — нет
То есть, файл может совсем пропасть, если сбойнет во время переименования? На FAT нет транзакций, там может. Но на NTFS метаданные вроде как журналируются, так что переименование либо случится, либо нет, и оба варианта здесь нормально проходят.
А>Мне нужно сделать запись в файл, но так, чтобы это было безопасно на случай непредвиденных сбоев А>То есть есть, если в процессе записи в файл произойдет отключение питания — это не приведёт к потере данных А>В Linux-e есть чудесный трюк: писать в другой файл, а затем переименовать его. А>В Linux-e переименование — атомарная операция, а как быть в Windows? А>( CreateFileTransacted не предлагать — нужно решение для XP )
В подобной ситуации я выкрутился созданием нескольких файлов и последующим вычитыванием последнего валидного из них. Переименовыванием в винде тоже как бы атомарное, но на практике с ним я видел проблемы, типа пустого файла после ресета.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, Аноним, Вы писали:
А>Мне нужно сделать запись в файл, но так, чтобы это было безопасно на случай непредвиденных сбоев А>То есть есть, если в процессе записи в файл произойдет отключение питания — это не приведёт к потере данных А>В Linux-e есть чудесный трюк: писать в другой файл, а затем переименовать его. А>В Linux-e переименование — атомарная операция, а как быть в Windows? А>( CreateFileTransacted не предлагать — нужно решение для XP )D
В линухе, переименование, кстати, тоже не во всех ситуациях атомарно. (Да и вообще, физически операции записи более чем в один сектор диска атомарными в принципе не могут быть без специальных мер типа двойной записи и журнала). Но вероятность сбоя, таки да, в силу организации типичных ФС значительно ниже.
Здравствуйте, andrey.desman, Вы писали:
AD>Здравствуйте, Аноним, Вы писали:
А>>проблема в переименовании. В Linux — это атомарная операция в в Windows — нет
AD>То есть, файл может совсем пропасть, если сбойнет во время переименования? На FAT нет транзакций, там может. Но на NTFS метаданные вроде как журналируются, так что переименование либо случится, либо нет, и оба варианта здесь нормально проходят.
А Microsoft где-то пишет, что переименование на NSTF — атамарное. Я такого не видел (((
Можно, конечно, взять этот вариант как практически приемлемый, но мне хочется решить это задачку теоретически, чтобы работало абсолютно всегда-всегда
Здравствуйте, Аноним, Вы писали:
А>Мне нужно сделать запись в файл, но так, чтобы это было безопасно на случай непредвиденных сбоев А>То есть есть, если в процессе записи в файл произойдет отключение питания — это не приведёт к потере данных А>В Linux-e есть чудесный трюк: писать в другой файл, а затем переименовать его. А>В Linux-e переименование — атомарная операция, а как быть в Windows? А>( CreateFileTransacted не предлагать — нужно решение для XP )
Все зависит от того, что подразумевается под потерей данных и какая планируется реакция
системы после восстановления. Если задача — обеспечить гарантию того, что данные всегда
будут находиться в согласованном состоянии, то это решается с помощью сигнального флага.
Если вкратце — в системе создается флаг, контролирующий текущее состояние файла.
Перед записью новых данных создается резервная копия файла, а затем флаг сбрасывается,
обозначая начало операции. С этого момента данные файла считаются логически утерянными.
Дальше следует запись, а после нее флаг снова устанавливается, индицируя завершение.
Резервная копия удаляется (опционально). Если в процессе записи происходит сбой, то
при следующем запуске программа будет в состоянии определить последнюю версию файла,
находящуюся в непротиворечивом состоянии.
Роль флага может выполнять что угодно, имеющее персистентность. Ключ реестра или даже бит
внутри самого файла. Главное, чтобы была возможность обеспечить строгий порядок выполнения —
сначала сброс флага, затем запись данных, затем восстановление флага. Если порядок гарантируется
аппаратно, то флаг всегда будет иметь состояние, не противоречащее логическому состоянию файла.
В Windows такую гарантию может обеспечить сброс файловых буферов на диск между фазами транзакции.
Но есть еще другие сценарии, в которых без настоящей поддержки аппаратуры не обойтись.
Здравствуйте, MasterZiv, Вы писали:
MZ>On 04.05.2011 17:15, Аноним 294 wrote: >> В Linux-e переименование — атомарная операция, а как быть в Windows?
MZ>Подозреваю всё же, что это не в линуксе, а в конкретной файловой системе. MZ>В ext3fs.
Во всех родных юниксовых FS переименование атомарное в том смысле, что операция выполняется целиком без разрыва (новое имя указывает на тот файл, куда указывало старое имя). А то, о чём Вы говорите — это уже вопрос журналирования FS.
хммм. переименование не атомарно? Хорошо, а если сделать так: записать данные во временный файл и сделать хардлинк на этот файл (нтфс умеет, хотя в XP там в функции мемори лик живет =) beware! ), ну а временное имя файла удалить (соответственно хардлинк называется так, как должен быть назван конечный файл).
В этом случае тоже могут быть чудеса в виде 'пустых файлов после ресета'?
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Let it be! — Давайте есть пчелу!
Re: запись файла как транзакция
От:
Аноним
Дата:
08.05.11 05:33
Оценка:
Может, в формате файла предусмотреть в конце его спецметку, типа "запись завершена, все ОК".
Если файл читается, и в конце эта метка присутствует — работаем с файлом. Если метки нет, то
файл записан со сбоем. Инфу следует игнорировать.
Также, если в файл надо добавлять инфу по частям, на каждую часть тоже можно предусмотреть подобную метку.