Microsoft nie ma w dzisiejszych czasach zwyczaju deprecjonowania pewnych rzeczy, ale kiedy to robią, to z jakiegoś powodu – i na pewno nie dlatego, że chcą utrudnić ci życie. Wręcz przeciwnie, prawie zawsze dzieje się tak dlatego, że opracowali lepsze i nowocześniejsze sposoby rozwiązywania tych samych problemów.
Ale przyzwyczajenia są trudne do złamania; zapytaj, skąd wiem. Zbyt często widzę ludzi trzymających się starszego sposobu wykonania jakiegoś zadania, nawet jeśli istnieje lepszy sposób.
Chciałbym podzielić się kilkoma ostatnimi przykładami, które pomogą nam zilustrować, w jaki sposób używanie przestarzałych funkcji SQL Server nadal nas gryzie. W tej pierwszej części chcę omówić…
procesy systemowe
Tabela systemowa sys.sysprocesses
został zastąpiony w SQL Server 2005 przez zestaw dynamicznych widoków zarządzania (DMV), w szczególności sys.dm_exec_requests
, sys.dm_exec_sessions
i sys.dm_exec_connections
. Oficjalna dokumentacja sys.sysprocesses
ostrzega:
Niedawny przykład
Niedawno jeden z naszych zespołów badał problem z opóźnieniem czytnika dzienników. Zwracamy tutaj dużą uwagę na opóźnienia, a także wszelkie długotrwałe transakcje, ze względu na wpływ na technologie korzystające z czytnika dzienników — takie jak grupy dostępności i replikacja transakcyjna. Nasze pierwsze ostrzeżenia są zwykle widoczne na pulpicie nawigacyjnym, który przedstawia opóźnienie czytnika dziennika w stosunku do czasu trwania transakcji (wyjaśnię momenty, w których oznaczyłem t0
i t1
wkrótce):
Ustalili, powiedzmy w czasie t0
, że pewna sesja miała otwartą transakcję blokującą proces odczytu dziennika. Najpierw sprawdzili dane wyjściowe DBCC INPUTBUFFER
, aby spróbować określić, jak trwała ta sesja, ale wyniki po prostu wskazywały, że podczas transakcji wyemitowano również inne partie:
event_type parameters event_info -------------- ---------- --------------- Language Event 0 SET ROWCOUNT 0;
Zauważ, że DBCC INPUTBUFFER
ma również bardziej wydajny zamiennik w nowoczesnych wersjach:sys.dm_exec_input_buffer
. I chociaż nie ma wyraźnego ostrzeżenia o wycofaniu, oficjalna dokumentacja DBCC
polecenie ma to delikatne pchnięcie:
Po otrzymaniu niczego z bufora wejściowego zapytali sys.sysprocesses
:
SELECT spid, [status], open_tran, waittime, [cpu], physical_io, memusage, last_batch FROM sys.sysprocesses WHERE spid = 107;
Wyniki były podobnie bezużyteczne, przynajmniej jeśli chodzi o określenie, co robiła sesja, aby utrzymać otwartą transakcję i zakłócić działanie czytnika dziennika:
Zaznaczam physical_io
kolumna, ponieważ ta wartość wywołała dyskusję na temat tego, czy chcą zaryzykować zabicie sesji spania. Pomyślano, że w przypadku, gdy wszystkie fizyczne operacje we/wy są zapisami, zabicie transakcji może skutkować długotrwałym i destrukcyjnym wycofaniem — potencjalnie jeszcze pogorszy problem. Nie zamierzam podawać rzeczywistych czasów, ale powiedzmy, że przekształciło się to w dłuższą rozmowę i pozostawiło system w tym stanie od czasu t0
do czasu t1
na powyższym wykresie.
Dlaczego to jest problem
Problem w tym konkretnym przypadku polega na tym, że spędzili ten czas na rozważaniu decyzji opartej na niekompletnych informacjach. Czy te wejścia/wyjścia odczytują lub zapisują? Jeśli użytkownik ma otwartą transakcję i tylko przeczytał dużo danych, wycofanie tej transakcji ma znacznie mniejszy wpływ, niż gdyby zmienili dużo danych. Więc zamiast sys.sysprocesses
, zobaczmy, co bardziej nowoczesny DMV, sys.dm_exec_sessions
, może pokazać nam tę sesję:
SELECT session_id, [status], open_transaction_count, cpu_time, [reads], writes, logical_reads, last_request_start_time, last_request_end_time FROM sys.dm_exec_sessions WHERE session_id = 107;
Wyniki:
Tutaj widzimy, że sys.dm_exec_sessions
rozkłada fizyczne I/O oddzielnie na odczyty i zapisy. Dzięki temu możemy podjąć bardziej świadomą decyzję, znacznie szybciej niż t1 - t0
, o potencjalnym wpływie wycofania. Jeśli wszystkie I/O są zapisane i w zależności od tego, jak wysoka jest ich liczba, możemy się trochę bardziej wahać i być może poświęcić czas na zlokalizowanie użytkownika (abyśmy mogli uderzyć go w dłonie lub zapytać, dlaczego mają otwartą transakcję ). Jeśli wiemy, że to głównie odczyty, możemy zamiast tego skłonić się do zabicia sesji i wymuszenia wycofania transakcji.
Jasne, sys.sysprocesses
ma dbid
i waittime
. Ale dbid
i tak jest niewiarygodne i marginalnie przydatne, szczególnie w przypadku zapytań między bazami danych; jest dużo lepsze informacje w sys.dm_tran_locks
. Informacje o oczekiwaniu (czas i typ ostatniego oczekiwania) można znaleźć w sys.dm_exec_requests
, ale znacznie bardziej szczegółowe informacje są dostępne w sys.dm_exec_session_wait_stats
(dodane w SQL Server 2016). Często słyszałem wymówkę, że sys.dm_exec_sessions
brakowało open_tran
, ale open_transaction_count
został ponownie dodany w SQL Server 2012. Nie ma więc powodu, aby nawet myśleć o użyciu sys.sysprocesses
dzisiaj.
Jeśli chcesz dowiedzieć się, jak często sys.sysprocesses
zostało przywołane od czasu ostatniego ponownego uruchomienia programu SQL Server, możesz uruchomić to zapytanie względem liczników wydajności DMV:
SELECT instance_name, cntr_value FROM sys.dm_os_performance_counters WHERE [object_name] LIKE N'%:Deprecated Features%' AND instance_name = N'sysprocesses' ORDER BY cntr_value DESC;
Jeśli naprawdę chcesz uniknąć snu tej nocy lub po prostu chcesz stale dodawać do listy rzeczy, o które się martwisz, usuń predykat z instance_name
. To da ci przerażające, ogólne pojęcie o tym, ile rzeczy działają w twoich instancjach, które w końcu będziesz musiał zmienić.
W międzyczasie pobierz sp_WhoIsActive
, niezwykle użyteczna procedura składowana Adama Machanica do monitorowania i rozwiązywania problemów z procesami SQL Server w czasie rzeczywistym. Wdrożyliśmy tę składowaną procedurę w każdej instancji w naszym środowisku i Ty też powinieneś, niezależnie od innych zaawansowanych narzędzi do monitorowania, których możesz również używać.
Następnym razem
W części 2 opowiem trochę o SQL Server Profiler, aplikacji, której ludzie używają częściej ze względu na znajomość niż cokolwiek innego – nie zdając sobie sprawy, jak niebezpieczna może być.