2012-05-21 3 views
0

Я создаю службу Windows, которая запускается при подключении определенного USB-ключа. Что он делает: просто: обратитесь к FTP-серверу, загрузите несколько файлов и храните их в (зашифрованном) на USB-накопителе. Архив можно открыть только для чтения с помощью инструмента, предоставляемого клиенту (но это не имеет отношения к моей проблеме).Контейнер архива на основе транзакций

Услуга используется для синхронизации USB с главным сервером (в основном, как Dropbox, но только загрузка и синхронизированные папки находятся на съемном носителе). Архив может вырасти до нескольких гигабайт. Около 1 ГБ файлов обновляются каждую неделю на ключах около 400 пользователей.

Поскольку весь процесс обновления является прозрачным для пользователя, есть не ничтожно малый шанс, что они отключить USB-когда данные записываются в архив (даже если я ставлю какое-то кричащее, кричащего предупреждение: НЕ ОТКРЫТЬ). Для исправления архива потребуется загрузить его снова целиком, что означает, что на уже загруженных серверах тратится большая часть трафика.

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

Вопрос здесь: Как я могу гарантировать постоянство данных во все времена? В частности, как заставить операции ввода-вывода работать как транзакции? Что ты предлагаешь? Должен ли я что-то реализовать самостоятельно? Или есть уже контейнеры, которые предлагают эту функцию?

Это то, что я получил до сих пор:

  • Создать новый архив, переименуйте на совершение: невозможно, архив слишком велик.
  • Zip/Tar/7z: непригодны, неудачная запись испортит архив
  • Truecrypt: непригоден, так как он требует драйвера файловой системы (права администратора, чтобы пользователи усеивают не есть).
  • Все, что требует сопоставления файловой системы в файл: неподходящий, довольно уверен, что вы не можете этого сделать, не будучи администратором, но если это возможно, было бы здорово.
  • Хранение файлов в SQLite DB: это ACID, чтобы действительно быть решением. Тем не менее, это потребует разделения файлов, поскольку SQLite имеет ограниченную емкость BLOB. Не очень элегантный, но я готов идти именно так. Также журнал транзакций SQLite может стать довольно большим при хранении больших блоков.
  • Реализуйте это самостоятельно: Я бы предпочел избежать этого как можно больше, но я не боюсь это делать. Я просто считаю эту тему довольно сложной.

Если этот вопрос слишком общий, пожалуйста, переместите его в SU или что-то еще.

+0

Является ли USB отформатирован как NTFS? – Fanael

+0

@Fanael Да, иначе архив все равно не поместился. –

+0

В этом случае, и если вас интересует только Vista и выше, возможно, вам стоит попробовать «CreateFileTransacted» и его друзей? – Fanael

ответ

1

Возможно, вы захотите попробовать использовать что-то вроде svn или git для загрузки зашифрованных различий; они обычно могут быть использованы для восстановления файла локально, если он поврежден. Или просто скачайте diffs и используйте patch для создания последней версии файла.

У вас возникли другие проблемы, если пользователь отключает флэш-накопитель, когда он находится в процессе записи данных. Многие из них ненадежны (на уровне флэш-блока, а не на уровне файловой системы) и могут быть повреждены до такой степени, что файловая система журналов, такая как NTFS или EXT3, не может восстановить. Здесь более подробно: https://superuser.com/questions/290060/can-flash-memory-be-physically-damaged-if-power-is-interrupted-while-writing

+0

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

+0

Вы можете запускать git локально; вы можете использовать его возможности для версии, чтобы перестроить файл, который поврежден. – patwood

0

все довольно просто, действительно. напишите на временный, затем установите мастер, если запись закончится, а затем удалите и повторите попытку.

+1

Как я уже сказал, это невозможно, архив слишком велик. –

+1

Не делайте это слишком простым: ** [Переименовывает() без fsync() безопасно?] (Http://stackoverflow.com/questions/7433057/is-rename-without-fsync-safe) ** – sehe

0

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