Чтение/запись целостности сопоставления файловLinux

Ответить
Anonymous
 Чтение/запись целостности сопоставления файлов

Сообщение Anonymous »

У меня есть довольно большой набор (порядка десятков ГБ) постоянных данных и сервер, который должен работать с ними и в конечном итоге изменять их. Сервер должен компилироваться в 64-битных системах Windows и Linux.
Сопоставление файлов кажется естественным выбором. Однако это вызывает вопросы относительно целостности данных. Изменения, внесенные в страницы памяти, асинхронно отражаются в базовом файле. А в случае аварийного завершения (сбой процесса сервера или отключение питания) данные, скорее всего, окажутся в несогласованном состоянии.
Я хотел бы решить эту проблему, используя транзакционный подход. техника. То есть все изменения, внесенные в сопоставление файлов, должны рассматриваться как «временные», и в случае аварийного завершения должна быть возможность их откатить. В какой-то момент изменения должны быть «зафиксированы», это должна быть атомарная операция, после которой изменения считаются постоянными.
На данный момент я придумал следующие стратегии проектирования и буду будем рады услышать больше идей и предложений.
  • Файл журнала WAL с явным запросом доступа для записи.
Всякий раз, когда приложению требуется доступ на запись к странице памяти, оно вызывает соответствующую функцию. Если это первый раз, когда страница будет изменена (с момента последней фиксации), ее содержимое будет сохранено в файле журнала.
Затем, чтобы зафиксировать изменения, будет выполнено следующее:
  • Очистить файл журнала (

    Код: Выделить всё

    FlushFileBuffers
    в Windows, fsync в Linux).
  • Сбросить сопоставление файлов (

    Код: Выделить всё

    FlushViewOfFile
    в Windows, msync в Linux).
  • Очистить базовый файл сопоставления.
  • Измените размер файла журнала на 0. .
  • Очистить файл журнала. И, при необходимости, удалите его.
При следующей инициализации приложения появится файл журнала ненулевого размера — это означает, что последний изменения не были зафиксированы, и их необходимо откатить. Во время отката страницы считываются из файла журнала и копируются в исходный файл данных.
Примечание: приведенное выше гарантирует согласованность в случае, если мы предполагаем, что этот файловый ввод-вывод, хотя и асинхронный, выполняется по порядку. Это означает, что если мы скопируем содержимое страницы в файл журнала, а затем изменим доступную память, которая, в свою очередь, будет генерировать ввод-вывод в файл данных, эти два асинхронных ввода-вывода выполняются по порядку, т.е. файл журнала. обновляется раньше файла данных.
  • Неявный доступ на запись, инициируемый нарушением прав доступа.
То же, что и выше, за исключением того, что приложение не запрашивает доступ для записи явно. Вместо этого файл отображается как доступный только для чтения (

Код: Выделить всё

PAGE_READONLY). Всякий раз, когда приложение пытается выполнить запись в это место, возникает исключение. В Windows это можно обрабатывать через SEH, в Linux должна быть возможность обрабатывать обработчик сигнала SIGSEGV
.
Во время обработки содержимое страницы сохраняется в файл журнала. , и его защита изменяется на PAGE_READWRITE.
Затем во время фиксации восстанавливается защита страницы только для чтения.
Я уже реализовал это на Windows, кажется, работает правильно, и я считаю, что то же самое можно сделать и в Linux.
  • Использовать защиту памяти от копирования при записи.
    Это грубая идея, я пока не разбираюсь во всех деталях, но теоретически можно использовать защиту памяти PAGE_WRITECOPY (не конечно, если подобная защита существует в Linux).
    При этом все грязные страницы будут выделены ОС автоматически, заполнение данными останется прежним. Затем, на этапе фиксации, эти страницы должны быть идентифицированы и скопированы в базовый файл данных (с защитой WAL), а затем защита состояния страниц должна быть восстановлена.
  • Файл с поддержкой журнала.
    Теоретически должен быть способ справиться с этим на уровне файловой системы. То есть отображение памяти должно поддерживаться файлом, поддерживающим режим транзакций. Все изменения в файле следует рассматривать как временные до тех пор, пока файл не будет «зафиксирован», и выполнять откат, если файл закрыт без такой фиксации.

    < /ol>

    Итак, вот какие идеи мне пришли в голову.
    Вариант (1) кажется самым «безопасным» вариант, не мешает ли он таким вещам, как обработка исключений/сигналов. При первом написании страницы производительность также снижается меньше (известно, что обработка исключений требует больших усилий).
    Однако у нее есть следующие недостатки:
  • Необходимо вызывать явную функцию каждый раз, когда мы должны изменить данные. Необходимо обновить весь код, который должен работать с этими данными, что, конечно, очень неудобно.
  • Каждый раз проверять, не загрязнена ли страница, может быть затратно. Необходимо иметь соответствующую структуру данных (битовую маску, карту или их комбинацию). В случае, когда на одной странице происходит множество изменений (что вполне вероятно), это может быть более эффективным, чем обработка исключения/сигнала ОС только один раз.
Вариант (2) кажется более рискованным. Но до сих пор я мог написать доказательство концепции, и, похоже, оно работает отлично.
Вариант (3) – я не знаю, возможно ли это вообще, т. е. есть ли обычный API для этого. Но теоретически это может быть полезно, поскольку копирование при записи полностью выполняется в режиме ядра, и нет необходимости обрабатывать эти вещи явно.
И, наконец, вариант (4). На самом деле это должно быть лучше во всех смыслах, поскольку поведение, подобное транзакциям, происходит именно там, где и должно быть - на уровне файла, когда изменения сопоставления файлов окончательно сбрасываются. Также самый быстрый и простой в отношении. кодирование.
Единственный вопрос: возможно ли это вообще? Существует ли файловая система, поддерживающая это?
Это мои идеи на данный момент. Буду рад услышать больше.
Заранее спасибо.

Подробнее здесь: https://stackoverflow.com/questions/790 ... -integrity
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»