ADO.NET - проблема с множественными подключениями к БД

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
mtripathi
Сообщения: 9
Зарегистрирован: 14 июл 2011, 09:02

ADO.NET - проблема с множественными подключениями к БД

Сообщение mtripathi » 14 июл 2011, 22:03

Борюсь (пока безуспешно) с такой проблемой: при подключении к БД из приложения .NET через ADO.NET provider v.2.6.5, не могу к этой же БД подключиться другим приложением - сервер отвечает: "IO error during "CreateFile (open)" operation for file "xxx.fdb". Error while trying to open file. The process cannot access the file because it is being used by another process."

Если мой .NET клиент не подключен к БД - любое другое приложение подключается без проблем. Но в этом случае мой клиент не может подключиться с той же ошибкой.

Такое ощущение, что ADO клиент требует от сервера эксклюзивного доступа к БД, но в строке коннекта ничего похожего не нашел чтобы отключить эту функцию. Кто-нибудь сталкивался с подобной проблемой?

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение hvlad » 15 июл 2011, 00:01

Выглядит как использование встроенного (embedded) сервера

mtripathi
Сообщения: 9
Зарегистрирован: 14 июл 2011, 09:02

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение mtripathi » 15 июл 2011, 11:00

нет, это исключено. я специально проверял, что клиент подключен к полнофункциональному серверу Firebird, а не к embedded.
netstat показывает наличие tcp-подключения от моего клиента к серверу на порту 3050

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение hvlad » 15 июл 2011, 12:41

Значит или другое приложение лезет через embedded (или другой экземпляр сервера), или .Net приложение лезет на сервер к другой БД, а "проблемную" открывает через embedded.

Чудес не бывает. Два разных приложения пытаются открыть файл БД в эксклюзивном режиме каждое.

mtripathi
Сообщения: 9
Зарегистрирован: 14 июл 2011, 09:02

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение mtripathi » 15 июл 2011, 13:32

Согласен, чудес не бывает. Поэтому я взял ProcessExplorer, чтобы посмотреть кто держит файл. Оказалось, файл держит только 1 процесс - fbserver.exe, в обеих случаях (в случае когда подключен мой клиент, и в случае, когда подключено другое приложение. Другое приложение - это на самом деле IBExpert, который уж точно не будет лезть через Embedded). Таким образом, версия о том что другое приложение или мой клиент лезет через embedded - отпадает.

Попробую резюмировать еще раз всю последовательность:

Шаг 1. Подключаюсь к БД из моего приложения, использующего ADO .NET - проблем нет, подключается великолепно.
Шаг 2. При подключенном моем приложении (см. Шаг 1), пробую подключиться к этой же базе через IBExpert - FB сервер отвечает, что файл занят
Шаг 3. При подключенном моем приложении (см. Шаг 1), проверяю кто держит файл БД с помощью ProcessExplorer - файл держит только 1 процесс - fbserver.exe.
Шаг 4. Отключаю свой клиент.
Шаг 5. Проверяю, кто держит файл БД с помощью ProcessExplorer - файл никем не занят (как и ожидалось, ибо клиент отключен)
Шаг 6. Подключаюсь к БД с помощью IBExpert - проблем нет, подключается великолепно (ибо мой клиент не подключен)
Шаг 7. Пробую подключиться моим клиентом - сервер отвечает что файл занят
Шаг 8. Проверяю, кто держит файл БД с помощью ProcessExplorer - файл держит только 1 процесс - fbserver.exe.

Дополнительно делаю еще 1 шаг, чтобы убедиться что проблема не в сервере Firebird:

Шаг 9. При подключенном IBExpert (см.Шаг 6) пробую подключиться любым другим клиентом, не использующим ADO .NET - подключается без проблем хоть 10 раз.

Таким образом, вопрос: почему на Шаге 2 и Шаге 7 сервер отвечает, что файл занят?

Единственная разумная версия, которая мне приходит в голову, - клиент ADO .NET каким-то образом требует от сервера монопольного доступа к файлу.
Вопрос - каким таким образом он это делает и как это предотвратить? Или я где-то не прав в цепочке рассуждений?

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение Dimitry Sibiryakov » 15 июл 2011, 14:37

Угу, неправ.
mtripathi писал(а):Другое приложение - это на самом деле IBExpert, который уж точно не будет лезть через Embedded).
Дальше можно не читать, ибо это предположение - ошибочно. В состав IBExpert входит Firebird Embedded, которым он пользуется направо и налево.

isql рулит!!!

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение hvlad » 15 июл 2011, 15:41

mtripathi писал(а):Единственная разумная версия, которая мне приходит в голову, - клиент ADO .NET каким-то образом требует от сервера монопольного доступа к файлу.
Вопрос - каким таким образом он это делает и как это предотвратить?
Никаким. Клиент не может потребовать от сервера такого доступа.
Можно перевести БД в шатдаун, можно потребовать сделать валидацию, которая не допускает посторонних подключений, но сообщение об ошибке будет другим.
mtripathi писал(а):Или я где-то не прав в цепочке рассуждений?
Конечно. Скорее всего ты что-то не видишь. Например второй экземпляр сервера...

mtripathi
Сообщения: 9
Зарегистрирован: 14 июл 2011, 09:02

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение mtripathi » 15 июл 2011, 16:48

УРА, НАШЕЛ!!! Спасибо Дмитрию, натолкнул на мысль. Хотя он был и не совсем прав )))
Возможно IBExpert и в самом деле может использовать embedded server, точно не знаю, но зато я на 100% уверен что в моем случае он подключается к настоящему FB серверу. (доказательства в Шагах 9 и 8 моего предыдущего поста).

Оказалось, что проблема на самом деле не в IBExpert, не в embedded server и не в ADO.NET. Проблема в том, как fbserver обрабатывает символические ссылки.

Поскольку я считаю это как минимум некорректностью реализации сервера, а как максимум - багом, то детально опишу причины проблемы.
Сформулировать можно в общем случае так: "При одновременном подключении 2 и более независимых клиентов к одному и тому же файлу БД через FB server, при условии, что один из клиентов сообщает серверу путь к файлу, отличающийся от пути, сообщенного серверу первым подсоединившимся клиентом, сервер отказывает клиенту в подключении мотивируя это тем, что файл уже используется другим приложением".

В каком случае пути к одному и тому же файлу могут отличаться? в случае, если используется символическая ссылка на каталог. Пример:
На диске С: в каталоге db лежит файл application.fdb.
На этом же диске создана символическая ссылка (symlink или junction) на каталог db с именем sdb.
В этом случае, к файлу application.fdb можно "добраться" двумя разными путями, которые абсолютно эквивалентны с точки зрения операционной системы:

1) c:\db\application.fdb
2) c:\sdb\application.fdb

Однако же, эти два пути представляются серверу Firebird абсолютно различными! Поэтому, если вы попытаетесь подключиться ЛЮБЫМ клиентом (даже упомянутым Дмитрием isql.exe) к одной и той же БД, используя при первом подключении путь (1), а при втором - путь (2), сервер отвергнет вторую попытку подключения!!!

Вероятнее всего, когда сервер проверяет путь к БД, к которой клиент хочет подключиться, он сравнивает его с путями уже имеющихся подключений. Не найдя совпадения, сервер считает что он этой БД не подключен, а следовательно требует монопольного доступа к файлу. Что не есть корректно (на мой взгляд).

Предлагаемое решение: перед проверкой пути к БД, сервер должен разрешить все символические ссылки и сравнивать абсолютные дисковые пути, лишенные символических ссылок.

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение kdv » 16 июл 2011, 11:49

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

p.s. симлинки на базу - это надо же додуматься :-)

mtripathi
Сообщения: 9
Зарегистрирован: 14 июл 2011, 09:02

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение mtripathi » 16 июл 2011, 13:29

Мое предположение о некорректности относилось НЕ к проверке транзакций в активном состоянии, а к проверке путей к файлу базы данных.
Как я описал в предыдущем посте, экспериментально установлено, что сервер при коннекте не ресолвит пути к БД в случае наличия в них симлинков.
Если разработчики намерены разобраться в проблеме и ее устранить, могу предоставить подтверждающие мои слова скриншоты/видео и прочие необходимые доказательства.
Если нет, или если разработчики не считают это проблемой - не беда, главное что workaround найден.

Насчет "додуматься" до использования симлинков - все достаточно просто. Я думаю, что я не первый, кто решил размещать локальную БД приложения в профиле пользователей, в специально отведенном для данных приложения каталоге - %APPDATA%. Как известно, доступность иных каталогов на запись отнюдь не гарантирована последними версиями Windows c функциями UAC и прочими заморочками безопасности. Также известно, что путь %APPDATA% содержит симлинки в Windows 7 для совместимости с ранними версиями Windows, пример:
- в Windows XP:
%APPDATA% = \documents and settings\user\Application Data - абсолютный дисковый путь
- В Windows 7:
%APPDATA% = \Users\user\Appdata\Roaming - абсолютный дисковый путь
%APPDATA% = \documents and settings\user\Application Data - путь с символической ссылкой для совместимости с ХР и более ранними.

каким образом этот эффект отражается на проблеме с доступом к базе данных Firebird из разных приложений - детально и с примерами описано в предыдущем посте.

Поэтому авторство идеи с симлинками принадлежит, к счастью, не мне. :-)

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение hvlad » 16 июл 2011, 14:30

Также известно, что путь %APPDATA% содержит симлинки в Windows 7
Макросы с симлинками не надо путать.

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение hvlad » 16 июл 2011, 14:31

Я, персонально, не считаю это проблемой. Если кто-то считает иначе - трекер ещё не закрыли.

mtripathi
Сообщения: 9
Зарегистрирован: 14 июл 2011, 09:02

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение mtripathi » 16 июл 2011, 15:18

hvlad писал(а):
Также известно, что путь %APPDATA% содержит симлинки в Windows 7
Макросы с симлинками не надо путать.
Вы не поняли. Я не говорил, что макрос %APPDATA% является симлинком. Я говорил, что в Windows 7 каталог \documents and settings\user\Application Data содержит символические ссылки, конкретнее: "documents and settings" ссылается на каталог "Users", а "Application Data" ссылается на "AppData\Roaming".

mtripathi
Сообщения: 9
Зарегистрирован: 14 июл 2011, 09:02

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение mtripathi » 16 июл 2011, 15:57

hvlad писал(а):Я, персонально, не считаю это проблемой. Если кто-то считает иначе - трекер ещё не закрыли.
http://tracker.firebirdsql.org/browse/CORE-3558

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение Dimitry Sibiryakov » 17 июл 2011, 14:50

mtripathi писал(а):Предлагаемое решение: перед проверкой пути к БД, сервер должен разрешить все символические ссылки и сравнивать абсолютные дисковые пути, лишенные символических ссылок.
А в Windows есть API для разрешения символических ссылок? Что-то я беглым взглядом в MSDN такого не нашёл...

mtripathi
Сообщения: 9
Зарегистрирован: 14 июл 2011, 09:02

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение mtripathi » 17 июл 2011, 16:07

Я тоже такого API не видел. Скорее всего, надо разбирать путь на компоненты и смотреть - является ли конкретный каталог символической ссылкой, или нет, а затем заново собирать путь

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение Dimitry Sibiryakov » 17 июл 2011, 23:07

О, я наконец-то вспомнил какую часть букваря аффтар пропустил мимо ушей: http://ibase.ru/devinfo/dontdoit.htm

mtripathi
Сообщения: 9
Зарегистрирован: 14 июл 2011, 09:02

Re: ADO.NET - проблема с множественными подключениями к БД

Сообщение mtripathi » 18 июл 2011, 21:21

Dimitry Sibiryakov писал(а):О, я наконец-то вспомнил какую часть букваря аффтар пропустил мимо ушей: http://ibase.ru/devinfo/dontdoit.htm
увы, поздно :-)
к счастью, уважаемый Дмитрий из багтрекера изволил согласиться со мной, признав вышеописанное несчастье багом, хотя и мелким (в чем я с ним полностью согласен). Так что, возможно уже в ближайшие десятилетия, наши внуки будут читать сей почтенный документ: http://ibase.ru/devinfo/dontdoit.htm без первого пункта :-)

Ответить