Problem
Klient zgłasza: Comarch ERP Optima nie uruchamia się. Przy starcie wyskakuje komunikat:
Cannot open database „CDN_KNF_Konfiguracja” requested by the login. The login failed.
Login failed for user 'CDNOperator’.
Na pierwszy rzut oka wygląda to na problem z uprawnieniami loginu CDNOperator – a to przecież standardowy, wewnętrzny login Optimy, który „zawsze działał”. Klient nie zmieniał nic w konfiguracji. Skąd więc odmowa?
Co się stało
CDN_KNF_Konfiguracja to wspólna baza konfiguracyjna. Baza istniała na serwerze i była ONLINE – ale jej tryb dostępu to SINGLE_USER. W trybie single-user baza przyjmuje dokładnie jedno połączenie. A to jedno połączenie było już zajęte – przez samą aplikację Optima.
Każda kolejna próba połączenia (drugi użytkownik, usługa, ponowne uruchomienie aplikacji) dostaje odmowę – stąd komunikat o „nieudanym logowaniu”. Co gorsza, problem nie dotyczył jednej bazy: wiele baz CDN_ naraz było w trybie SINGLE_USER.
Diagnoza – krok po kroku
1. Które bazy są w trybie single-user?
SELECT name, user_access_desc, state_desc FROM sys.databases WHERE user_access_desc <> 'MULTI_USER';
2. Kto trzyma sesję na bazie?
SELECT DB_NAME(database_id) AS baza, login_name, status, host_name, program_name FROM sys.dm_exec_sessions WHERE database_id > 4;
W naszym przypadku wynik jasno wskazał winowajcę:
| baza | login | status | host | program |
|---|---|---|---|---|
| CDN_KNF_Konfiguracja | CDNOperator | sleeping | SERWER | Comarch ERP Optima |
| CDN___BAZA_KLIENTA | SERWER\Osoba | sleeping | SERWER | Microsoft SQL Server Management Studio – Query |
Pierwsza baza była zablokowana przez samą aplikację, druga – przez okno SSMS administratora.
3. Czy to efekt restore’u?
SELECT destination_database_name, restore_date, user_name
FROM msdb.dbo.restorehistory
WHERE destination_database_name IN (
SELECT name FROM sys.databases WHERE user_access_desc = 'SINGLE_USER'
)
ORDER BY restore_date DESC;
Wspólna data przywrócenia w wynikach = potwierdzenie, że to backup/restore przeniósł tryb single-user.
Naprawa
Ustawiamy bazy z powrotem na MULTI_USER:
ALTER DATABASE [CDN_KNF_Konfiguracja] SET MULTI_USER WITH ROLLBACK IMMEDIATE; ALTER DATABASE [CDN___BAZA_KLIENTA] SET MULTI_USER WITH ROLLBACK IMMEDIATE;
A żeby nie zostało żadnej bazy single-user, można wykonać pętlę:
DECLARE @sql nvarchar(max) = N''; SELECT @sql += N'ALTER DATABASE [' + name + N'] SET MULTI_USER WITH ROLLBACK IMMEDIATE;' + CHAR(10) FROM sys.databases WHERE user_access_desc = 'SINGLE_USER' AND state_desc = 'ONLINE'; PRINT @sql; -- najpierw podgląd -- EXEC sp_executesql @sql; -- odkomentuj po akceptacji
Ważne uwagi:
WITH ROLLBACK IMMEDIATEzrywa aktywne połączenia – w naszym wypadku to było bezpieczne (sesja sleeping), ale przy pracujących użytkownikach lepiej zrobić to w ciszy, poza godzinami pracy, albo najpierw zamknąć Optimę.- Nie ruszamy baz w stanie
RESTORING(środek lub przerwany restore) – najpierw trzeba dokończyć/odwołać restore. - Po naprawie wszystkie bazy
CDN_*powinny być MULTI_USER – weryfikacja:SELECT name FROM sys.databases WHERE user_access_desc <> 'MULTI_USER';
Skutek
Po ustawieniu baz na MULTI_USER aplikacja wystartowała bez błędów. Żadne dane nie zostały utracone – operacja dotyczyła wyłącznie trybu dostępu do bazy.
