У меня есть процесс, который:
rename()
системный вызов для замены существующего файла.Мы делаем это, потому что нам нужны атомарные обновления файлов, а rename()
spec говорит:
Если newpath уже существует, он будет заменен атомарно, так что не будет точки, в которой другой процесс, пытающийся получить доступ к newpath, обнаружит, что он отсутствует. Однако, вероятно, будет окно, в котором и oldpath, и newpath ссылаются на переименованный файл.
Мы полагаемся на такое поведение.
Но вот загвоздка - совсем недавно, после перехода на новый NetApp (режим кластера, из режима 7), у нас был процесс, который очень иногда падает с ENOENT
- Данный файл или каталог отсутствует.
Под «очень редко» я имею в виду - 4 или 5 раз за последние несколько недель, процесс, который происходит каждые 5 минут или около того.
Я выясняю у поставщика, может ли это быть ошибкой на их сервере NFS.
Но на самом деле я пытаюсь выяснить, применима ли эта гарантия атомарности к NFS. Кто-нибудь может прояснить мне, если rename()
гарантия атомарности применяется к мультиклиентским сценариям NFS? Я не уверен, что эта функция работала, но никогда гарантированный в первую очередь.
Из: RFC1813
Процедура RENAME переименовывает файл, указанный в from.name в каталоге, from.dir, в to.name в каталоге, to.dir. Операция должна быть атомарной для клиента.
Если это актуально, у нас есть клиенты SL 6.5, которые обращаются к хранилищам данных NFS на ONTAP-CDOT 8.3.
Избежание условий гонки в NFS
Это всегда увлекательная задача, и единственный известный мне способ обхода без переписывания приложений - это смонтировать общий ресурс с опциями. sync
и измените сервер NFS на использование no_wdelay
. Я не помню, как установить no_wdelay в NetApp.
Обратной стороной этого метода является то, что если у вас есть много одновременных операций записи в этот общий ресурс, они будут работать экспоненциально медленнее. Вы можете спросить NetApp, как установить no_wdelay на этом ресурсе, или просто опишите им проблему. У них могут быть идеи получше. Я не прикасался к NetApp как минимум 8 лет.