Гарантируется ли последовательная очистка данных в файле с отображением памяти?

Я пытаюсь реализовать механизм хранения файлов, который содержит несколько записей переменного размера в одном файле с гарантией того, что набор записей всегда можно будет восстановить в согласованное состояние, даже если система выйдет из строя на аппаратном уровне.

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

Есть два очевидных способа обойти это, но оба нежелательны:

  1. Сбросьте содержимое, затем напишите подтверждение и слейте его. Добавление дополнительной промывки может снизить производительность.
  2. Включите контрольную сумму в подтверждение (потребуется прочитать содержимое, чтобы подтвердить, что оно действительно).

Я использую С# в Windows (32- и 64-разрядная версия) и реализацию файла с отображением памяти .Net 4.0.


person Kennet Belenky    schedule 21.07.2010    source источник
comment
Вторая идея (проверка данных, метки времени, порядкового номера и контрольной суммы) кажется законной. Однако в целом вам следует рассматривать кластеры высокой доступности с отдельными машинами в сети. Все записи или журнальные записи должны быть реплицированы по сети на две или более машины. Вы не можете получить какую-либо гарантию на одну машину, и точка.   -  person rwong    schedule 14.10.2014


Ответы (2)


Это слишком низкий уровень и специфика ОС для C#. попробуйте использовать Windows API из C и очень внимательно прочитайте спецификации API.

person ruslik    schedule 21.07.2010

Вы пытались использовать FileOptions.WriteThrough в базовом файловом потоке? Это может помочь, поскольку отключает буферизацию. Другие идеи заключаются в том, чтобы сохранить отдельный файл, содержащий подтверждения, в качестве последнего записанного смещения, если он не соответствует вашему размеру файла (например, из-за отключения электроэнергии), вы можете просто обрезать его до этого размера.

person Homde    schedule 17.11.2010
comment
Это хорошие идеи с точки зрения восстановления после сбоев. К сожалению, они не применяются к файлам с отображением памяти. Файлы MM всегда отключают WriteThrough, потому что они используют базовый менеджер страниц ОС для обработки буферизации. Ведение журнала подтверждений также является хорошей идеей, но у него есть другие проблемы. Тогда для каждой файловой операции потребуется два сброса (один для файла MM, один для журнала). Еще более проблематичным является то, что с файлами MM вы не знаете, когда сброс завершен. В лучшем случае вы можете указать ОС начать очистку, но вы не получите подтверждения по завершении. Это делает детерминированный журнал неприемлемым. - person Kennet Belenky; 22.11.2010
comment
@Kennet Belenky: Сброс данных странный, сравните с Java. Может быть, вы могли бы использовать обычный FileOutputStream для журнала (журнал короткий, поэтому большой разницы в скорости не будет)? IIUYC потеря неподтвержденной записи не так уж и плоха, поэтому вы можете очищать журнал реже. - person maaartinus; 25.08.2012
comment
@maaartinus Java API определенно легче рассуждать, но и он не идеален. Приятно, что он дает гарантию полного сброса по возвращении. Однако было бы еще лучше, если бы он предоставил вам асинхронное уведомление, чтобы вы могли заниматься своими делами. Время поиска в 10 мс при очистке вращающегося диска — это долгое время бездействия. - person Kennet Belenky; 28.08.2012
comment
@Kennet Belenky: я не могу вспомнить ничего в Java, подходящего для этого асинхронного уведомления. Использование Callable с ExecutorService многословно (как и многие вещи в Java), но тривиально для всего, что вы не хотите заставлять сидеть без дела. - person maaartinus; 28.08.2012