Wczoraj moja baza danych SQL Server była w porządku. Dziś jest prawie bezużyteczny - spowalnia go od pięciu do dwudziestu, w zależności od tego, kiedy go uderzyłem.
Niektóre dane zostały dodane do serwera podczas procesu ładowania z dnia na dzień, ale nic tak jak wolumin, który powinien mieć tak duży wpływ na bazę danych. Około 50 000 rekordów w postaci zwykłego tekstu (bez XML lub innych drobiazgów).
Serwer został załatany dziś rano, zanim go ponownie uruchomiliśmy. Jednak żaden z naszych innych serwerów baz danych, które również zostały załatane, nie zachowuje się inaczej.
Wydaje się, że Monitor zasobów sugeruje, że wadliwe jest jego IO dysku. Cały czas działa na prawie 100% pojemności pliku .mdf, nawet jeśli w bazie danych niewiele się dzieje. Dostęp do Templog.ldf również działa dość wysoko.
Nikt tutaj nie jest ekspertem DBA (wszyscy jesteśmy programistami z różną liczbą umiejętności SQL) i wszyscy jesteśmy zaskoczeni tym, co się stało. Próbowaliśmy uruchomić sp_updatestats i przenieść niektóre duże indeksy na różne dyski, ale bezskutecznie.
Myślę, że to musi mieć coś wspólnego z łatką - wydaje się to zbyt częstym przypadkiem. Kolega jest przekonany, że to obciążenie danych spowodowało wzrost wielkości pliku mdf do punktu, w którym spowodowało to, że plany wykonania stały się nieefektywne.
Co do cholery to spowodowało? Jak możemy się dowiedzieć i co możemy zrobić, aby to naprawić?
EDYTOWAĆ:
Używanie sp_WhoIsActive
nie ujawnia niczego niezwykłego. Rejestruje moje własne użycie sproc i niektóre polecenia od kolegi, który obecnie próbuje przenieść inny indeks. To prawdopodobnie trzyma teraz DB, ale wcześniej działało tak samo źle.
Jest to standardowa wersja SQL Server 2008 R2. SELECT @@VERSION
daje:
Microsoft SQL Server 2008 R2 (SP2) - 10.50.4033.0 (X64)
9 lipca 2014 16:04:25
Prawa autorskie (c) Microsoft Corporation Standard Edition (64-bit) na Windows NT 6.1 (Build 7601: Service Pack 1) (Hypervisor )
Serwer ma 72 GB pamięci RAM i trzy czterordzeniowe procesory 2 GHz.
Łatka została zastosowana tylko do systemu Windows. Nie wprowadzono żadnych zmian poza łatką.
Wybrane ustawienia:
_id name value minimum maximum value_in_use description is_dynamic is_advanced
1540 min memory per query (KB) 1024 512 2147483647 1024 minimum memory per query (kBytes) 1 1
1541 query wait (s) -1 -1 2147483647 -1 maximum time to wait for query memory (s) 1 1
1543 min server memory (MB) 0 0 2147483647 16 Minimum size of server memory (MB) 1 1
1544 max server memory (MB) 65536 16 2147483647 65536 Maximum size of server memory (MB) 1 1
AKTUALIZACJA: Przenoszenie indeksów i tabel do różnych partycji dysku wydaje się poprawiać. Nadal jestem zdezorientowany, jak mogliśmy tak nagle osiągnąć punkt krytyczny z tak drastycznymi skutkami.
źródło
SELECT * FROM sys.configurations;
- chceszvalue, value_in_use
takich rzeczy jakmax server memory (MB)
. Przydałby się również numer kompilacjiSELECT @@VERSION;
, a także to, czy znajduje się on w hiperwizorze i czy cokolwiek zmieniło się na hoście od wczoraj (lub od ostatniego uruchomienia SQL Server).Odpowiedzi:
Może się zdarzyć, że niewielka ilość danych osiągnie określony limit w SQL Server, aby wymusić inny plan lub coś w tym rodzaju. To nie jest mało prawdopodobne. Ale fakt, że twoja płyta wydaje się być na służbie, prowadzi mnie do innego wniosku.
Istnieją dwa możliwe podstawowe powody spowolnienia.
Rzućmy okiem na część nr 1
Możliwe, że konfiguracja programu SQL Server może być zepsuta. Może to powodować poważne problemy dotyczące szybkości serwera i użycia dysku.
Najpierw sprawdź swoje podstawowe ustawienia serwera. Te podstawowe ustawienia
max server memory
,affinity I/O mask
,affinity mask
imax degree of parallelism
. Może być konieczne włączenie opcji zaawansowanych za pomocąshow advanced options
.Oto kompletny skrypt:
Porównaj wynik z udokumentowanymi wartościami w krokach instalacji. Czy nadal są takie same?
Może to mieć wiele powodów, dla których twój serwer zachowuje się tak dziwnie. Normalnie założę się, że
max server memory
po prostu się mylisz. Spowoduje to, że Twój SQL Server na stałe zmieni strony danych. Nie może zatrzymać wszystkiego w swojej pamięci. Oznacza to, że musi odczytać strony z dysku, zaktualizować go, natychmiast zapisać. Jeśli pojawi się kolejna aktualizacja, która używa tej samej strony do aktualizacji, nie można jej odczytać z pamięci. Zamiast tego serwer musi odczytać go ponownie z dysku. Po prostu zamiana ...Innym problemem może być zbyt duże powinowactwo do dysku lub procesów. Jeśli korzystałeś ze wspólnego serwera (SQL Server + inne usługi) z dedykowaną płytą dla SQL Server (co może być rzadkim przypadkiem, ale może być), może to być twój problem. Twój serwer zwykle miał na przykład 3 procesory dla procesów i jeden dla I / O. Pozostałe 12 procesorów jest wykorzystywane do innych usług. W takim przypadku maska koligacji jest nieprawidłowa i używa na przykład automatycznej konfiguracji. Oznacza to, że Twój serwer używa dynamicznie wszystkich 16 rdzeni do procesów i operacji we / wy. Jeśli masz uruchomione ogromne procesy, mogą one spowodować ogromne obciążenie dysku, którego może nie obsłużyć. Ale tak naprawdę nie wierzę, że to twoja sprawa. Byłoby to szybsze (choćby odrobinę), gdyby tak się stało, ale twoja sprawa jest wolniejsza.
Kolejnym problemem może być zbyt wysoki stopień równoległości. Co oznacza, że masz zbyt wiele wątków na biegu jałowym w jednej części zapytania. Może to również spowodować ogromne spowolnienie, jeśli równoległość nie będzie działać zgodnie z oczekiwaniami. Ale to nie opisuje w ogóle twojego wysokiego I / O.
Teraz spójrzmy również na część nr 2
Ładujesz kilka wierszy do swojego systemu. Nawet jeśli jest to zwykłe zadanie, może zwiększyć limit, w którym eskalują się twoje plany zapytań. Może być nawet tak, że wstawianie w połączeniu z SQL Server powoduje takie zachowanie.
Wspomniałeś, że już próbowałeś przenieść swoje indeksy na inną płytę, co wydaje się pomóc. Może się tak zdarzyć tylko dlatego, że podzieliłeś obciążenie na dwie różne płyty.
Może się zdarzyć, że Twoje wskaźniki zostały złamane, Twoje plany zostały złamane lub że Twoje statystyki są po prostu nieaktualne.
1. pozwala sprawdzić statystyki ostatniej aktualizacji Możesz to zrobić ręcznie przez interfejs dla każdego pojedynczego elementu statystyki. Co byłoby bólem. Lub możesz wypróbować ten kod:
To da ci pełną informację o każdym indeksie (i sterty) i statystykach za nimi. Nawet jeśli uruchomisz
sp_updatestats
, nie oznacza to, że statystyki zostały zaktualizowane. Część, w której aktualizacja jest dość trudna, nawet jeśli uruchomiszsp_updatestats
lub nawet jeśliauto update statistics
jest włączona, statystyki nie zostaną zaktualizowane na czas. Oto kilka punktów granicznych, kiedy aktualizacja jest potrzebna / generowana:Oznacza to, że Twoje statystyki mogą być nieaktualne, nawet jeśli uruchomisz aktualizację.
Możesz spojrzeć na powyższe zapytanie. Jeśli znajdziesz jakieś stare statystyki w niektórych tabelach, możesz chcieć uruchomić ręczną aktualizację statystyk dla tej tabeli:
Następnie możesz dać serwerowi kopniaka w tyłek, aby odrzucić wszystkie stare plany.
Jeśli chcesz po prostu wyczyścić wszystkie pamięci podręczne, możesz zamiast tego uruchomić to:
Spowoduje to wyczyszczenie wszystkich pamięci podręcznych, a nie tylko pamięci podręcznej planu. Zazwyczaj ostrzegałbym, aby użyć tego na serwerze produkcyjnym w fazie produkcyjnej. Ale ponieważ twój serwer obecnie nie działa, nie możesz za bardzo go skrzywdzić. Może to spowolnić na kilka sekund, może 1-2 minut, ponieważ musi odbudować wszystkie skrzynki, ale potem powinien biegać z odpowiednimi planami.
Innym powodem mogą być całkowicie rozdrobnione wskaźniki. Można to sprawdzić na całym serwerze za pomocą tego oświadczenia:
Jeśli fragmentacja jest bardzo wysoka, może być konieczna reorganizacja (fragmentacja <20%) lub całkowite przebudowanie (> 20%). Może to wywierać większy nacisk na płytę i powodować problemy. Z drugiej strony, jeśli indeksy są tak złe, prawdopodobnie ostatecznie pomogłoby bardziej niż szkodzi.
Oprócz tych dwóch powodów nadal może być trzeci problem
Możliwe, że twój serwer jest skonfigurowany prawdopodobnie, nie zmieniłeś żadnego kodu w tym czasie, po prostu dodałeś kilka wierszy. Wszystkie statystyki są aktualizowane, a wszystkie pamięci podręczne są odbudowywane. Wszystkie twoje wskaźniki są zreorganizowane w taki sposób, w jaki ich potrzebujesz, ale nadal - nic nie działa. Możliwe, że osiągnąłeś limit dostępnej pamięci w swoich procesach. Może potrzebujesz więcej. Możesz po prostu sprawdzić, czy istnieje proces, który próbuje uzyskać więcej pamięci niż masz.
Możesz to sprawdzić za pomocą tego polecenia:
Zapewni Ci listę wszystkich sesji zużywających pamięć. Może być jakieś zapytanie, które wciąż czeka na uzyskanie pamięci. Te zapytania można łatwo filtrować. Wszystkie sesje gdzie
granted_memory_kb IS NULL
. Są to sesje, które żądały pamięci, ale jej nie dostają. Inną rzeczą może być przyznana pamięć, która może być za niska. Możesz porównać kolumnyrequested_memory_kb
zgranted_memory_kb
. Żądane pokazuje, ile pamięci proces musi optymalnie uruchomić, a przyznane pokazuje pamięć, która jest włączona dla procesu. Jeśli proces wymaga 2 GB do uruchomienia, ale zajmuje tylko 2 MB ... możesz go zdobyć samodzielnie. ;-)Innym sposobem jest sprawdzenie
RESSOURCE_SEMAPHORE
:Możesz rzucić okiem na
waiter_count
igrantee_count
. Jeśli kelner ma wartość większą niż 0, masz presję na pamięć, co może powodować zamianę i ciśnienie dysku widoczne w perfmon.źródło
Oprócz możliwych awarii dysku sprawdź stan podsystemu RAID. Widzieliśmy coś podobnego i okazało się, że bateria kontrolera RAID uległa awarii, więc nie było dostępnej pamięci podręcznej zapisu - wszystkie zapisy musiały przejść bezpośrednio na dysk. Jedna uwaga - mogliśmy poczuć, że system zatrzymuje się podczas RDC.
źródło