Jak nie od dziś wiadomo, SQL Sever 2008 November CTP (CTP5) wprowadził szereg nowych funkcjonalności, jak choćby Resource Governor, SSMS z Intelli Sense dla składni T-SQL, FILESTREAM, plan freezing czy kompresja backupów. Są to nowości bardzo medialne i informacja o nich pojawia się praktycznie na wszystkich blogach, stronach, webcastach itd. Warto jednak wspomnieć, że w najnowszej wersji silnika SQL Server mamy także do czynienia z dużą grupą zmian wewnętrznych, mniej widowiskowych, które jednak są równie istotne. W tym poście chciałbym się przyjrzeć ulepszeniom i modyfikacjom, jakie dotyczą statystyk stanów oczekiwań.
Zacznijmy od rzeczy oczywistych, czyli od centralnego widoku systemowego
sys.dm_os_wait_stats. Pierwsza różnica polega na tym, że znacznie przybyło nowych stanów oczekiwań. Liczba typów stanów oczekiwań w SQL Server 2005 wynosiła 201 (250 po włączeniu specjalnej flagi 8001 -
DBCC TRACEON (8001,-1) ), natomiast w November CTP typów stanów oczekiwań jest aż 463, czyli ponad 200 więcej. Flaga 8001 już nie powoduje pojawienia się dodatkowych rekordów w widoku. Rola i struktura samego widoku pozostała bez zmian. Nadal agreguje on informacje o globalnych stanach oczekiwań od początku działania instancji lub ostatniego resetu na zasadzie przyrostowej. Nowe stany oczekiwań wiążą się po części z nowymi mechanizmami, jakie funkcjonują w Katmai. Ale to nie wszystko - jest też druga grupa. Nazwy 189 nowych stanów oczekiwań zaczynają się od przedrostka
PREEMPTIVE_. Nie są to bynajmniej stany "martwe" (agregują konkretne oczekiwania). Wydaje się, że dotyczą bardzo wewnętrznych kwestii systemu operacyjnego SQL Server - SQLOS (m.in.
PREEMPTIVE_OS_WAITFORSINGLEOBJECT,
PREEMPTIVE_OS_WRITEFILEGATHER). Jeżeli stany te nie zostaną usunięte w wersji RTM, to będziemy mogli oglądać ciekawe informacje statystyczne, o ile tylko stany typu PREEMPTIVE zostaną dobrze opisane.
Jeżeli chodzi o statystyki globalnych stanów oczekiwań (wypadkowych dla danej instancji - widok DMV
sys.dm_os_wait_stats), to w SQL Server 2008 stosujemy dokładnie taką samą metodę, jak w przypadku SQL Server 2005. Możemy więc wykorzystać choćby
ten skrypt, który przygotowałem specjalnie dla SQL Server 2005. Uruchomienie go na odciążonych instancjach SQL Server 2008 i SQL Server 2005 pokazuje ciekawe różnice. Dla Katmai otrzymamy następujące niezerowe stany oczekiwań:
Podczas gdy na SQL Server 2005 sytuacja wygląda następująco:
Jak widać, różnice są dość zasadnicze. Analizując statystyki stanów oczekiwań na SQL Server 2008, więcej stanów oczekiwań należy rozpatrywać jako nieszkodliwe (m.in.
REQUEST_FOR_DEADLOCK_SEARCH,
BROKER_TO_FLUSH).
Istotne ulepszenie dotyczy pewnej niedogodności związanej z widokiem
sys.dm_os_waiting_tasks. W SQL Server 2005 widok ten dawał informacje o statystykach oczekiwania sesji, które aktualnie na coś czekają. Były to więc informacje niezmiernie ulotne - oczekiwania są przecież bardzo chwilowe, jeśli więc sesja przestawała czekać lub zmieniała typ oczekiwania, to albo znikała z widoku, albo statystyki oczekiwań resetowały się. Nie było więc łatwego sposobu, żeby w środowisku produkcyjnym uzyskać informacje o tym, jakie są statystyki stanów oczekiwań konkretnego zapytania. Co prawda w SQL Server 2008 widok DMV
sys.dm_os_waiting_tasks działa na takiej samej zasadzie, mamy jednak do dyspozycji nowy mechanizm -
Extended Events wraz ze zdarzeniem rozszerzonym
wait_info:
SELECT
o.name as event_name,
c.name as column_name,
c.column_id,
c.column_type
FROM sys.dm_xe_objects o JOIN sys.dm_xe_object_columns c
ON (o.name = c.object_name)
WHERE o.name = 'wait_info';
Powyższe zapytania pokazuje, jakie informacje możemy uzyskiwać o stanach oczekiwań przy pomocy XEvents:
Wykorzystanie XEvents nie jest może najwygodniejsze, bo to zupełnie nowy framework współpracujący z ETW (
Event Tracing for Windows), poniższy skrypt powinien jednak trochę rozjaśnić całą koncepcję:
BEGIN TRY
DROP EVENT SESSION waitinfo_session ON SERVER;
END TRY
BEGIN CATCH END CATCH
GO
CREATE EVENT SESSION waitinfo_session ON SERVER
ADD EVENT sqlos.wait_info
ADD TARGET package0.etw_classic_sync_target
(SET default_etw_session_logfile_path = N'C:\temp\waitinfo.etl');
GO
ALTER EVENT SESSION waitinfo_session ON SERVER STATE = START;
GO
-- workload
-- (..)
ALTER EVENT SESSION waitinfo_session ON SERVER STATE = STOP;
GO
Aby powyższy skrypt zadziałał, trzeba kilku rzeczy dopilnować. Co oczywiste, konto, na którym działa usługa SQL Server, musi mieć dostęp do katalogu
C:\temp. Co mniej oczywiste, konto powinno także należeć do dwóch grup -
Performance Monitor Users i
Performance Log Users. Niestety standardowa instalacja November CTP nie dodaje konta do drugiej grupy. Po dodaniu konta do odpowiednich grup może być wymagany restart instancji.
Kiedy zagregujemy już odpowiednie dane do pliku
waitinfo.etl, warto je jakoś odczytać. W tym celu należy skonwertować plik ETL do bardziej przyjaznego formatu - CSV. Wykonamy więc następującą operację:
tracerpt waitinfo.etl
Otrzymamy dwa pliki:
dumpfile.csv oraz
summary.txt, z nich łatwiej odczytamy interesujące nas informacje. Dane te będzie jeszcze trzeba wrzucić do tabeli i odpowiednio powiązać, aby dostarczyły nam tego, czego oczekujemy. Widać więc, że badanie stanów oczekiwań z XEvents jest jeszcze niedopracowane i wymaga szeregu poprawek i uproszczeń. W każdym razie mi nie udało się w prosty sposób zmusić tego do efektywnej pracy zgodnej z moimi oczekiwaniami, ale pożyjemy - zobaczymy.
To tyle na moment obecny, jeśli zauważę jakieś dodatkowe ulepszenia lub różnice w obszarze tematyki stanów oczekiwań w SQL Server 2008, to w pierwszej wolnej chwili o tym napiszę.