Когда запись O_SYNC становится видимой в кэше страниц (файл mmap'd)? - PullRequest
3 голосов
/ 15 августа 2011

У меня есть файл mmap'd только для чтения / совместного использования, с несколькими потоками / процессами, считывающими данные одновременно.Один автор может изменять данные в любое время (используя мьютекс в отдельной области совместно используемой памяти).Изменения выполняются с помощью write () в базовом файле.Общая настройка является частью базы данных, которая предназначена для обеспечения согласованности транзакций.

Ряд произвольных страниц данных будет записан в любом порядке, и затем будет вызвана функция fdatasync ().Ничто в файле не указывает на эти измененные страницы, пока не будет записана корневая страница.Корневая страница записывается с использованием второго файлового дескриптора, который был открыт с помощью O_SYNC, поэтому запись не вернется, пока корневая страница не будет успешно записана.Все записываемые страницы являются частью области mmap, поэтому в конечном итоге они станут видимыми для всех читателей.

Вопрос в том, становится ли окончательная запись O_SYNC видимой сразу же, как только копирует ядропользовательский буфер в кеш страницы?Или он становится видимым только после завершения синхронной записи?Я немного прочитал код ядра, но не следовал ему все время;мне кажется, что пользовательские данные немедленно копируются в кэш страницы, а затем запланирована запись, а затем она ожидает завершения записи.Между тем, записанные данные уже присутствуют в кеше страницы и поэтому сразу видны процессам читателя.Это нежелательно, потому что если физическая запись фактически завершается с ошибкой, транзакция должна быть откатана, и читателям никогда нельзя разрешать видеть что-либо, что было написано неудачной транзакцией.кеш страницы?Я полагаю, что для безопасности я могу обернуть доступ к корневой странице мьютексом, но это добавляет уровень накладных расходов, которых было бы лучше избегать.

Ответы [ 2 ]

2 голосов
/ 15 августа 2011

В соответствии с формальным стандартом POSIX обновления в MAP_SHARED регионах могут появляться в любое время. Определение Synchronized I / O определяет, что запись будет возвращаться только после того, как данные будут помещены на физический носитель, но не говорит о данных, видимых другими процессами.

На практике в Linux это работает так, как вы описали - кеш страниц - это промежуточная область, из которой отправляются записи устройства, а отображение MAP_SHARED - представление кеша страниц.

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

0 голосов
/ 15 августа 2011

Вы должны использовать msync (2) для mmapped файлов.Смешивание записи и доступа к mmapped вызывает проблемы.

...