Previous Entry Share Next Entry
2016-01

нубский вопрос про unix/9p traditions

Я вот краем уха слышал, что в Unix'ах идеологически правильно, к примеру, если у нас есть какой-то browsable сетевой ресурс или устройство - интегрировать его как mount point, дабы дальше его всяческий софт мог использовать с этой точки монтирования, не заморачиваясь деталями.

Ну, nfs, smb, procfs и так далее.

А вот в каком месте (POSIX?) можно прочитать, как предполагается при этом жить с concurrency?
Т.е. вот я получил список файлов в папке, показал его юзеру, он что-то открыл и потом сделал "save" в ту же папку. А к тому времени на него напал какой-нибудь, ну не знаю, search indexer, или банально другой юзер файл открыл.

Хочется юзеру показать диалог "файл занят Васей", а индексеру сказать "отпусти файл временно", и всякое такое прочее.

Предположим, что у нас идеальный случай, и мы контролируем (можем запатчить) и приложение, и сетевой ресурс, и API файловой системы.

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

UPD: чтиво в тему, чтобы была понятна глубина кроличьей норы -
http://danluu.com/file-consistency/
http://0pointer.de/blog/projects/locking.html
http://0pointer.de/blog/projects/locking2
https://www.samba.org/samba/news/articles/low_point/tale_two_stds_os2.html

This entry was originally posted at http://wizzard.dreamwidth.org/455707.html. It has comment count unavailable comments. Please comment there using OpenID.

  • 1
wizzard0 December 16th, 2015
Оу.

lyuden December 16th, 2015
.lock файл при операциях записи ?

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

wizzard0 December 16th, 2015
Индексер уже открыл файл, а нам надо его вдруг подпатчить (e.g. append)


Edited at 2015-12-16 12:39 pm (UTC)

altmind December 16th, 2015
я может задам тупой вопрос - но нельзя ли файл открывать в неблокирующем режиме? если нет, нельзя ли файл копировать куда-то или делать снимок каким-нибудь ммапом для индексации?

lyuden December 16th, 2015
Блокирующее чтение по сети ? Это по моему не UNIX way. И ломает абстракцию файлов. Если это необходимо, то не надо использовать абстракцию файлов. Как то так.

wizzard0 December 16th, 2015
Индексер запущен на машине, на которую мы идем по сети, и не знает, что к ним идут по сети. Как это обычно бывает :)

lyuden December 16th, 2015
Я первый раз сталкиваюсь с проблемой, что аггрегатор данных должен ждать пока данные освободят. Так что я не думаю, что это обычная система :)


wizzard0 December 16th, 2015
Под линухом у нас advisory locks, под виндой индексер использует Shadow Copies, поэтому на практике такая проблема не возникает :) но advisory locks это баг, а shadow copies явно не входит в семантику файловой системы)

lyuden December 16th, 2015
Как то все сложно.

wizzard0 December 16th, 2015
> сложно.
Concurrency is hard

permea_kra December 16th, 2015
Скажем так, если дозапись в файл не предусмотрена форматом файла (логи), то лучше в него ничего не дозаписывать, а создать рядом новый. Потому что единственная гарантированно атомарная операция апдейта - это rename (2)
В теории в ядре линукса есть какие-то распределенные лок-менэджеры, но я про это ничего не знаю.

ex0_planet December 16th, 2015
в линухе есть inotify, по крайней мере узнать, что до файла доступается кто-то еще (сетевой демон) индексер может.

sab123 December 16th, 2015
Никаких гарантий. Настоящий Юникс на локальных файловых системах дает гарантию атомарности записи, что то, что в одной операции write() будет все вместе или видно или не видно читателям. Но криворукие люди из Сана не реализовали это на NFS. А потом другие криворукие люди от Линукса и на локальных файловых системах перестали давать гарантию (что создает массу геморроев, когда несколько процессов пишут добавления в один лог-файл).

Но вообще, конечно, виндовсные автоматические блокировки - вообще жуткая и кошмарная вещь, совершенно геморрой на геморрое.

hellouk December 28th, 2015
ни разу не видел перемешанных записей в логе и когда strac'ил nginx не видел никаких локов при записи в логи, даже когда несколько процессов, значит эта проблема как-то решена? Скажем запись размером в 4 КБ идет атомарно

wizzard0 December 30th, 2015
э... тут речь про разные проблемы

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

sab123 January 1st, 2016
Нет-нет, это та самая проблема. Буфер записи будет побит по границам блоков файловой системы. И части из нескольких буферов могут перемешаться, то есть скажем вместо AABB будет ABAB.

sab123 January 1st, 2016
Я видел очень регулярно. Просто всякие линуксные сервисы в курсе этой проблемы и синхронизируются. 4КБ - размер страницы и если я правиально помню, одновременно блока в линуксных файловых системах, если писать равно по стольку, то да, сохранится атомарность. А если писать просто текстовые строки, то они будут перемешиваться на границах блоков.

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

amarao_san December 16th, 2015
Отдавать пользователю EBUSY? Не юзерфрендли, но все посиксовые штуки, либо shared, либо "кого тапки, тот и первый".

amarao_san December 16th, 2015
Вообще, по-хорошему, я бы делал даже интереснее: ioctl, который позволяет получить специфичную ошибку на IO, если кто-то другой в это время начнёт в файл писать.

Но да, нифига не posix.

wizzard0 December 16th, 2015
Ну, не posix, но может какой-то другой стандарт это решил более продуманно, что ли...

amarao_san December 16th, 2015
Я думаю, надо перестать смотреть в этом вопросе на унылое легаси, которое таки не сделало эти блокировки, и написать свои. С нуля. Мандаторные. В том числе с "вытесняющей блокировкой" (поломай меня если кто-то начал писать) и т.д.

ex0_planet December 16th, 2015
а не изобретают ли в этом треде dbms?

amarao_san December 16th, 2015
Любая файловая система - это база данных, а код файловой системы - DBMS. Однако, она очень специфичная по API и очень высокопроизводительная на произвольный доступ внутри данных.

ex0_planet December 16th, 2015
ACID

amarao_san December 16th, 2015
Нет. В контексте метаданных можно танцевать вокруг ACID, в контексте данных, большая часть из ACID не выполняется. Изменения не атомарны, не изолированы, не durable (потому что файловый кеш и всё такое). Есть некое слабое их подобие за счёт fsync, но он не атомарен.

файловые системы - отличное доказательство, что за пределами ACID жизнь есть.

mbr December 16th, 2015
так оно и есть.

mbr December 16th, 2015
Ты пытаешься вендопроблемы вкостылить в linux. Не нужно. Другой подход.

Нужен лок на файл - делай это явно через fcntl F_SETLKW. Чаще, как сказали выше - делают просто .lock файл.

wizzard0 December 16th, 2015
Дефолтное поведение винды меня тоже не устраивает. Более того, там по ссылкам написано, как это образовалось (тоже легаси) и какие проблемы реально создает %)

alamar December 16th, 2015
Если файл открыт на аппенд, очевидно, индексер проиндексирует, сколько успеет.

KIO, кажется, неплохую абстракцию представляет. Правда, не совсем юникс-вей.

_winnie December 16th, 2015
CAS (compare-and-swap)? Индексируем (или копируем себе) файл без блокировок. Если после индексации обнаруживаем что его поменяли - когда-нибудь в будущем его переиндексируем.


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

  • 1
?

Log in

No account? Create an account