Kiedy baza danych SQL Server jest gotowa do przyjmowania zapytań?

11

W pliku dziennika błędów programu SQL Server znalazłem następujące wiersze:

2018-02-22 14:10:58.95 spid17s     Starting up database 'msdb'.
2018-02-22 14:10:58.95 spid16s     Starting up database 'ReportServer'.
2018-02-22 14:10:58.95 spid18s     Starting up database 'ReportServerTempDB'.
2018-02-22 14:10:58.95 spid19s     Starting up database 'XYZ'.

Jeśli przed tym czasie sprawdzę status bazy danych XYZ, ONLINEużywa ona następującej instrukcji:

SELECT state_desc FROM sys.databases WHERE name='XYZ'

... ale kiedy próbuję połączyć się z tą bazą danych za pomocą aplikacji C #, nie może połączyć się z bazą danych.

Błąd jest następujący:

Logowanie nie powiodło się dla użytkownika „asd”.
Powód: Nie można otworzyć jawnie określonej bazy danych.

Próbowałem trzech różnych użytkowników (użytkownik Windows, sa, użytkownik SQL Server zdefiniowany dla aplikacji). Problem występuje, gdy uruchamiam aplikację podczas uruchamiania systemu operacyjnego, ale jeśli uruchomię ją ręcznie po uruchomieniu, nie wystąpią żadne błędy, więc myślę, że wszystkie ustawienia programu SQL Server i zapory są prawidłowe.

Sprawdziłem też wcześniej, czy status usługi jest uruchomiony.

Co jeszcze powinienem sprawdzić, aby upewnić się, że baza danych jest rzeczywiście online i gotowa na zapytania?

Szukam klucza, który powiedziałby mi, że można odpytywać bazę danych, zamiast opóźniać (nawet nie na podstawie wyraźnego powodu).

Myślałem o skanowaniu dziennika błędów w poszukiwaniu tekstu „Uruchamianie bazy danych„ XYZ ””, ale oznacza to, że muszę dodać ustawienie dla aplikacji dla ścieżki dziennika błędów SQL Server. Oznacza to także wielokrotne czytanie pliku, dopóki nie znajdę tego wyrażenia.

Ahmed
źródło

Odpowiedzi:

23

Baza danych SQL Server jest gotowa do przyjmowania zapytań, gdy tylko:

SELECT DATABASEPROPERTYEX(N'database name', 'Collation')

nie wraca NULL.

Z dokumentacji DATABASEPROPERTYEX(Transact-SQL) :

Uwaga: ONLINEStatus może zostać zwrócony podczas otwierania bazy danych i nie został jeszcze odzyskany. Aby określić, kiedy baza danych może akceptować połączenia, przeprowadź kwerendę we właściwości sortowania DATABASEPROPERTYEX. Baza danych może akceptować połączenia, gdy sortowanie bazy danych zwraca wartość inną niż null. W przypadku baz danych Always On zapytaj database_statelub database_state_desckolumny z sys.dm_hadr_database_replica_states.

Paul White 9
źródło
3

Bazy danych SQL Server uruchamiają się, ale następnie muszą przeanalizować dziennik transakcji, aby przewinąć transakcje do przodu i do tyłu. Proces ten może trwać od milisekund do godzin (a nawet dni!) W przypadku długotrwałej transakcji wiele (przypuszczalnie tysiące) baz danych użytkowników lub baz danych z dużą ilością (przypuszczalnie dziesiątki tysięcy) wirtualnych plików dziennika.

Jeśli chcesz, aby aplikacja dostała się tylko po zakończeniu odzyskiwania i gdy baza danych jest gotowa, poproś aplikację o ponowne nawiązanie połączenia.

Jeśli chcesz, aby aplikacja mogła natychmiast uzyskać dostęp do programu SQL Server, ale być może nie będzie w stanie uruchomić żadnych zapytań, ustaw domyślną bazę danych na TempDB zamiast bazy danych użytkownika. Prawdopodobnie będzie on dostępny natychmiast, nawet gdy bazy danych użytkowników będą niedostępne.

Brent Ozar
źródło