Rozwiązywanie problemów z brakiem pamięci lub małą ilością pamięci w programie SQL Server
Symptomy
Program SQL Server używa złożonej architektury pamięci, która odpowiada złożonemu i bogatemu zestawowi funkcji. Ze względu na różne potrzeby pamięci może istnieć wiele źródeł zużycia pamięci i ciśnienia pamięci, co ostatecznie powoduje brak pamięci.
Występują typowe błędy wskazujące niską ilość pamięci w programie SQL Server. Przykłady błędów to:
- 701: Nie można przydzielić wystarczającej ilości pamięci do uruchomienia zapytania.
- 802: Nie można pobrać pamięci w celu przydzielenia stron w puli (dane lub strony indeksu).
- 1204: Nie można przydzielić pamięci dla blokad.
- 6322: Nie można przydzielić pamięci dla analizatora XML.
- 6513: Nie można zainicjować środowiska CLR z powodu ciśnienia pamięci.
- 6533: Domena aplikacji została zwolniona z powodu braku pamięci.
- 8318: Nie można załadować liczników wydajności SQL z powodu niewystarczającej ilości pamięci.
- 8356 lub 8359: Nie można uruchomić śledzenia ETW lub SQL z powodu małej ilości pamięci.
- 8556: Nie można załadować MSDTC z powodu niewystarczającej ilości pamięci.
- 8645: Nie można wykonać zapytania z powodu braku pamięci dla dotacji pamięci (sortowanie i tworzenie skrótów) Aby uzyskać więcej informacji, zobacz Jak rozwiązać problem z błędem 8645 programu SQL Server.
- 8902: Nie można przydzielić pamięci podczas wykonywania polecenia DBCC.
- 9695 lub 9696: Nie można przydzielić pamięci dla operacji usługi Service Broker.
- 17131 lub 17132: Niepowodzenie uruchamiania serwera z powodu niewystarczającej ilości pamięci.
- 17890: Nie można przydzielić pamięci z powodu stronicowania pamięci SQL przez system operacyjny.
- 18053: Błąd jest drukowany w trybie terse, ponieważ wystąpił błąd podczas formatowania. Śledzenie, ETW, powiadomienia itp. są pomijane.
- 22986 lub 22987: Błędy przechwytywania zmian danych z powodu niewystarczającej ilości pamięci.
- 25601: Aparat Xevent nie ma pamięci.
- 26053: Inicjowanie interfejsów sieciowych SQL nie powiodło się z powodu niewystarczającej ilości pamięci.
- 30085, 30086, 30094: Operacje pełnotekstowe SQL kończą się niepowodzeniem z powodu niewystarczającej ilości pamięci.
Przyczyna
Wiele czynników może spowodować niewystarczającą ilość pamięci. Takie czynniki obejmują ustawienia systemu operacyjnego, dostępność pamięci fizycznej, składniki korzystające z pamięci wewnątrz programu SQL Server i limity pamięci w bieżącym obciążeniu. W większości przypadków zapytanie, które kończy się niepowodzeniem z powodu błędu braku pamięci, nie jest przyczyną tego błędu. Ogólnie rzecz biorąc, przyczyny można zgrupować w trzy kategorie:
Przyczyna 1: Wykorzystanie pamięci zewnętrznej lub operacyjnej
Ciśnienie zewnętrzne odnosi się do wysokiego wykorzystania pamięci pochodzącego ze składnika poza procesem, który prowadzi do niewystarczającej ilości pamięci dla programu SQL Server. Musisz dowiedzieć się, czy inne aplikacje w systemie zużywają pamięć i przyczyniają się do niskiej dostępności pamięci. PROGRAM SQL Server jest jedną z niewielu aplikacji przeznaczonych do reagowania na wykorzystanie pamięci systemu operacyjnego przez zmniejszenie użycia pamięci. Oznacza to, że jeśli aplikacja lub sterownik żąda pamięci, system operacyjny wysyła sygnał do wszystkich aplikacji, aby zwolnić pamięć, a program SQL Server odpowie, zmniejszając użycie własnej pamięci. Kilka innych aplikacji odpowiada, ponieważ nie są one przeznaczone do nasłuchiwania tego powiadomienia. W związku z tym, jeśli program SQL Server zacznie zmniejszać użycie pamięci, pula pamięci zostanie zmniejszona i niezależnie od tego, które składniki potrzebują pamięci, mogą go nie uzyskać. W związku z tym zaczniesz uzyskać błędy 701 lub inne błędy związane z pamięcią. Aby uzyskać więcej informacji na temat dynamicznego przydzielania i zwalniania pamięci przez program SQL Server, zobacz Architektura pamięci programu SQL Server. Aby uzyskać bardziej szczegółową diagnostykę i rozwiązania problemu, zobacz Wykorzystanie pamięci zewnętrznej w tym artykule.
Istnieją trzy szerokie kategorie problemów, które mogą powodować wykorzystanie pamięci systemu operacyjnego:
- Problemy związane z aplikacjami: jedna lub wiele aplikacji łącznie wyczerpało dostępną pamięć fizyczną. System operacyjny odpowie na nowe żądania aplikacji dotyczące zasobów, próbując zwolnić część pamięci. Typowym podejściem jest znalezienie aplikacji zużywających pamięć i podjęcie niezbędnych kroków w celu zrównoważenia pamięci między nimi bez konieczności wyczerpania pamięci RAM.
- Problemy ze sterownikiem urządzenia: Sterowniki urządzeń mogą powodować stronicowanie zestawu roboczego wszystkich procesów, jeśli sterownik niepoprawnie wywołuje funkcję alokacji pamięci.
- Problemy z produktem systemu operacyjnego.
Aby uzyskać szczegółowe wyjaśnienie tych kroków i rozwiązywania problemów, zapoznaj się z MSSQLSERVER_17890.
Przyczyna 2: Wykorzystanie pamięci wewnętrznej, które nie pochodzi z programu SQL Server
Wykorzystanie pamięci wewnętrznej odnosi się do niskiej dostępności pamięci spowodowanej czynnikami wewnątrz procesu programu SQL Server. Niektóre składniki, które mogą być uruchamiane wewnątrz procesu programu SQL Server, są "zewnętrzne" dla aparatu programu SQL Server. Przykłady obejmują dostawców OLE DB (DLL), takich jak serwery połączone, procedury lub funkcje SQLCLR, procedury rozszerzone (XPs) i automatyzacja OLE (sp_OA*
). Inne obejmują programy antywirusowe lub inne programy zabezpieczeń, które wstrzykiwają biblioteki DLL wewnątrz procesu do celów monitorowania. Problem lub słaba konstrukcja dowolnego z tych składników może prowadzić do dużego zużycia pamięci. Rozważmy na przykład buforowanie 20 milionów wierszy danych z zewnętrznego źródła do pamięci programu SQL Server. Jeśli chodzi o program SQL Server, żaden urzędnik pamięci nie będzie zgłaszać wysokiego użycia pamięci, ale pamięć zużywana w procesie programu SQL Server będzie wysoka. Ten wzrost pamięci z połączonej biblioteki DLL serwera, na przykład, spowoduje, że program SQL Server zacznie zmniejszać użycie pamięci (patrz powyżej) i utworzy niskie warunki pamięci dla składników wewnątrz programu SQL Server, powodując błędy braku pamięci. Aby uzyskać bardziej szczegółową diagnostykę i rozwiązania problemu, zobacz Wewnętrzne wykorzystanie pamięci, które nie pochodzi z programu SQL Server.
Uwaga 16.
Kilka bibliotek DLL firmy Microsoft używanych w przestrzeni procesów programu SQL Server (na przykład MSOLEDBSQL, SQL Native Client) jest w stanie połączyć się z infrastrukturą pamięci programu SQL Server na potrzeby raportowania i alokacji. Możesz uruchomić polecenie select * from sys.dm_os_memory_clerks where type='MEMORYCLERK_HOST'
, aby uzyskać listę z nich i śledzić użycie tej pamięci dla niektórych ich alokacji.
Przyczyna 3: Wewnętrzne ciśnienie pamięci pochodzące ze składników programu SQL Server
Wewnętrzne ciśnienie pamięci pochodzące ze składników wewnątrz aparatu programu SQL Server może również prowadzić do błędów braku pamięci. Istnieją setki składników śledzonych za pośrednictwem clerks pamięci, które przydzielają pamięć w programie SQL Server. Aby rozwiązać ten problem, należy określić, którzy urzędnicy pamięci są odpowiedzialni za największe alokacje pamięci. Jeśli na przykład okaże się, że OBJECTSTORE_LOCK_MANAGER
urzędnik pamięci wyświetla dużą alokację pamięci, musisz zrozumieć, dlaczego menedżer blokady zużywa tyle pamięci. Mogą istnieć zapytania, które uzyskują wiele blokad. Te zapytania można zoptymalizować przy użyciu indeksów, skracając wszelkie transakcje, które przechowują blokady przez długi czas, lub sprawdzając, czy eskalacja blokady jest wyłączona. Każdy urzędnik pamięci lub składnik ma unikatowy sposób uzyskiwania dostępu do pamięci i korzystania z nich. Aby uzyskać więcej informacji, zobacz typy urzędników pamięci i ich opisy. Aby uzyskać bardziej szczegółową diagnostykę i rozwiązania problemu, zobacz Wewnętrzne użycie pamięci przez aparat programu SQL Server.
Wizualna reprezentacja typów ciśnienia pamięci
Na poniższym wykresie przedstawiono typy ciśnienia, które mogą prowadzić do braku pamięci w programie SQL Server:
Narzędzia diagnostyczne do zbierania danych rozwiązywania problemów
Do zbierania danych dotyczących rozwiązywania problemów można użyć następujących narzędzi diagnostycznych:
Monitor wydajności
Skonfiguruj i zbierz następujące liczniki przy użyciu monitor wydajności:
- Pamięć:Dostępne mb/s
- Proces:Zestaw roboczy
- Proces:Bajty prywatne
- SQL Server:Menedżer pamięci: (wszystkie liczniki)
- SQL Server:Buffer Manager: (wszystkie liczniki)
WIDOKI DMV lub DBCC MEMORYSTATUS
Można użyć sys.dm_os_memory_clerks lub DBCC MEMORYSTATUS , aby zaobserwować ogólne użycie pamięci w programie SQL Server.
Raport o użyciu pamięci w warstwie Standardowa w programie SSMS
Wyświetlanie użycia pamięci w programie SQL Server Management Studio:
- Uruchom program SQL Server Management Studio i połącz się z serwerem.
- W Eksplorator obiektów kliknij prawym przyciskiem myszy nazwę wystąpienia programu SQL Server.
- W menu kontekstowym wybierz pozycję Raporty Zużycie pamięci w raportach>>standardowych.
PsSDiag lub SQL LogScout
Alternatywnym, zautomatyzowanym sposobem przechwytywania tych punktów danych jest użycie narzędzi, takich jak PSSDiag lub SQL LogScout.
Jeśli używasz narzędzia PSSDiag, skonfiguruj go do przechwytywania modułu zbierającego narzędzia Perfmon i modułu zbierającego błędy niestandardowej diagnostyki\pamięci SQL.
Jeśli używasz usługi SQL LogScout, skonfiguruj ją do przechwytywania scenariusza pamięci .
W poniższych sekcjach opisano bardziej szczegółowe kroki dla każdego scenariusza (wykorzystanie pamięci zewnętrznej lub wewnętrznej).
Metodologia rozwiązywania problemów
Jeśli od czasu do czasu pojawia się błąd braku pamięci lub przez krótki okres, może wystąpić krótkotrwały problem z pamięcią, który rozwiązuje się sam. W takich przypadkach może nie być konieczne podjęcie działań. Jeśli jednak błąd występuje wiele razy na wielu połączeniach i utrzymuje się przez kilka sekund lub dłużej, postępuj zgodnie z diagnostyką i rozwiązaniami w poniższych sekcjach, aby dalej rozwiązywać problemy z błędami pamięci.
Wykorzystanie pamięci zewnętrznej
Aby zdiagnozować niskie warunki pamięci w systemie poza procesem programu SQL Server, użyj następujących metod:
Zbierz liczniki monitor wydajności. Sprawdź, czy aplikacje lub usługi inne niż program SQL Server zużywają pamięć na tym serwerze, sprawdzając następujące liczniki:
- Pamięć:Dostępne mb/s
- Proces:Zestaw roboczy
- Proces:Bajty prywatne
Oto przykład zbierania dzienników programu Perfmon przy użyciu programu PowerShell:
clear $serverName = $env:COMPUTERNAME $Counters = @( ("\\$serverName" +"\Memory\Available MBytes"), ("\\$serverName" +"\Process(*)\Working Set"), ("\\$serverName" +"\Process(*)\Private Bytes") ) Get-Counter -Counter $Counters -SampleInterval 2 -MaxSamples 1 | ForEach-Object { $_.CounterSamples | ForEach-Object { [pscustomobject]@{ TimeStamp = $_.TimeStamp Path = $_.Path Value = ([Math]::Round($_.CookedValue, 3)) } } }
Przejrzyj dziennik zdarzeń systemu i poszukaj błędów związanych z pamięcią (na przykład małej ilości pamięci wirtualnej).
Przejrzyj dziennik zdarzeń aplikacji pod kątem problemów z pamięcią związaną z aplikacją.
Oto przykład skryptu programu PowerShell służącego do wykonywania zapytań dotyczących dzienników zdarzeń systemu i aplikacji dla słowa kluczowego "pamięć". Możesz używać innych ciągów, takich jak "zasób" dla wyszukiwania:
Get-EventLog System -ComputerName "$env:COMPUTERNAME" -Message "*memory*" Get-EventLog Application -ComputerName "$env:COMPUTERNAME" -Message "*memory*"
Rozwiąż wszelkie problemy z kodem lub konfiguracją dla mniej krytycznych aplikacji lub usług, aby zmniejszyć użycie pamięci.
Jeśli aplikacje oprócz programu SQL Server zużywają zasoby, spróbuj zatrzymać lub ponownie uruchomić te aplikacje lub rozważyć ich uruchomienie na osobnym serwerze. Te kroki spowodują usunięcie użycia pamięci zewnętrznej.
Wykorzystanie pamięci wewnętrznej, które nie pochodzi z programu SQL Server
Aby zdiagnozować wykorzystanie pamięci wewnętrznej spowodowane przez moduły (DLL) wewnątrz programu SQL Server, użyj następujących metod:
Jeśli program SQL Server nie używa zablokowanych stron w pamięci (interfejs API AWE), większość pamięci jest odzwierciedlana w liczniku Process:Private Bytes (
SQLServr
wystąpienie) w monitor wydajności. Ogólne użycie pamięci pochodzące z aparatu programu SQL Server jest odzwierciedlone w liczniku SQL Server:Memory Manager: Total Server Memory (KB). Jeśli znajdziesz znaczącą różnicę między wartością Process:Private Bytes i SQL Server:Memory Manager: Total Server Memory (KB), ta różnica prawdopodobnie pochodzi z biblioteki DLL (serwer połączony, XP, SQLCLR itd.). Jeśli na przykład bajty prywatne to 300 GB, a łączna ilość pamięci serwera wynosi 250 GB, około 50 GB ogólnej pamięci w procesie pochodzi poza aparatem programu SQL Server.Jeśli program SQL Server używa zablokowanych stron w pamięci (interfejs API AWE), trudniej jest zidentyfikować problem, ponieważ monitor wydajności nie oferuje liczników AWE, które śledzą użycie pamięci dla poszczególnych procesów. Ogólne użycie pamięci w a aparatze programu SQL Server jest odzwierciedlone w liczniku SQL Server:Memory Manager: Total Server Memory (KB). Typowy proces:Wartości bajtów prywatnych mogą się różnić w zakresie od 300 MB do 1–2 GB. Jeśli znajdziesz znaczące użycie procesów:bajtów prywatnych poza tym typowym użyciem, różnica prawdopodobnie pochodzi z biblioteki DLL (serwer połączony, XP, SQLCLR itd.). Jeśli na przykład licznik bajtów prywatnych wynosi 4–5 GB, a program SQL Server używa zablokowanych stron w pamięci (AWE), duża część bajtów prywatnych może pochodzić spoza aparatu programu SQL Server. Jest to technika przybliżenia.
Użyj narzędzia Tasklist, aby zidentyfikować wszystkie biblioteki DLL załadowane wewnątrz obszaru programu SQL Server:
tasklist /M /FI "IMAGENAME eq sqlservr.exe"
Możesz również użyć następującego zapytania, aby sprawdzić załadowane moduły (DLL) i sprawdzić, czy istnieją jakieś nieoczekiwane elementy.
SELECT * FROM sys.dm_os_loaded_modules
Jeśli podejrzewasz, że moduł serwera połączonego powoduje znaczne zużycie pamięci, możesz skonfigurować go tak, aby zabrakło procesu, wyłączając opcję Zezwalaj na przetwarzanie . Aby uzyskać więcej informacji, zobacz Tworzenie serwerów połączonych . Nie wszyscy dostawcy serwera połączonego OLE DB mogą zabrakło procesu. Aby uzyskać więcej informacji, skontaktuj się z producentem produktu.
W rzadkich przypadkach, w których są używane obiekty automatyzacji OLE (
sp_OA*
), można skonfigurować obiekt do uruchamiania w procesie poza programem SQL Server, określając wartość kontekstu 4 (tylko lokalny (.exe) serwera OLE. Aby uzyskać więcej informacji, zobacz sp_OACreate.
Użycie pamięci wewnętrznej przez aparat programu SQL Server
Aby zdiagnozować wykorzystanie pamięci wewnętrznej pochodzącej ze składników wewnątrz aparatu programu SQL Server, użyj następujących metod:
Rozpocznij zbieranie liczników monitor wydajności dla programu SQL Server: SQL Server:Buffer Manager i SQL Server: Menedżer pamięci.
Wykonaj wiele zapytań względem urzędów zarządzania pamięcią programu SQL Server, aby sprawdzić, gdzie występuje największe zużycie pamięci wewnątrz aparatu:
SELECT pages_kb, type, name, virtual_memory_committed_kb, awe_allocated_kb FROM sys.dm_os_memory_clerks ORDER BY pages_kb DESC
Alternatywnie można obserwować bardziej szczegółowe
DBCC MEMORYSTATUS
dane wyjściowe i sposób jego zmiany po wyświetleniu tych komunikatów o błędach.DBCC MEMORYSTATUS
Jeśli zidentyfikujesz wyraźnego sprawcę wśród urzędników pamięci, skoncentruj się na uwzględnieniu specyfiki zużycia pamięci dla tego składnika. Oto kilka przykładów:
- Jeśli urzędnik
MEMORYCLERK_SQLQERESERVATIONS
pamięci zużywa pamięć, zidentyfikuj zapytania korzystające z ogromnych dotacji pamięci i zoptymalizuj je za pośrednictwem indeksów, zapisz je ponownie (na przykład usuńORDER by
, lub zastosuj wskazówki dotyczące udzielania pamięci ( zobacz wskazówki dotyczące udzielania pamięci (zobacz wskazówki dotyczące udzielania min_grant_percent i max_grant_percent). Możesz również utworzyć pulę zarządców zasobów, aby kontrolować użycie pamięci przydzielanej pamięci. Aby uzyskać szczegółowe informacje o udzielaniu pamięci, zobacz Rozwiązywanie problemów z niską wydajnością lub małą ilością pamięci spowodowanych przez przydziały pamięci w programie SQL Server. - Jeśli jest buforowana duża liczba planów zapytań ad hoc,
CACHESTORE_SQLCP
urzędnik pamięci będzie używać dużych ilości pamięci. Zidentyfikuj niesparametryzowane zapytania, których plany zapytań nie mogą być ponownie używane i parametryzują je, konwertując je na procedury składowane przy użyciu metody lub przy użyciusp_executesql
FORCED
parametryzacji. Jeśli włączono flagę śledzenia 174, możesz ją wyłączyć, aby sprawdzić, czy rozwiąże to problem. - Jeśli magazyn pamięci podręcznej planu
CACHESTORE_OBJCP
obiektów zużywa zbyt dużo pamięci, zidentyfikuj, które procedury składowane, funkcje lub wyzwalacze używają dużej ilości pamięci i ewentualnie przeprojektuj aplikację. Często może się to zdarzyć z powodu dużych ilości baz danych lub schematów z setkami procedur w każdym z nich. -
OBJECTSTORE_LOCK_MANAGER
Jeśli urzędnik pamięci wyświetla duże alokacje pamięci, zidentyfikuj zapytania, które stosują wiele blokad i optymalizują je przy użyciu indeksów. Skróć transakcje, które powodują, że blokady nie są zwalniane przez długi czas na określonych poziomach izolacji lub sprawdź, czy eskalacja blokady jest wyłączona. - Jeśli obserwujesz bardzo duże
TokenAndPermUserStore
(select type, name, pages_kb from sys.dm_os_memory_clerks where name = 'TokenAndPermUserStore'
), możesz użyć flagi śledzenia 4618 , aby ograniczyć rozmiar pamięci podręcznej. - Jeśli zauważysz problemy z pamięcią związane z olTP w pamięci pochodzącej z
MEMORYCLERK_XTP
urzędnika pamięci, możesz zapoznać się z tematem Monitorowanie i rozwiązywanie problemów z użyciem pamięci dla metadanych OLTP w pamięci i zoptymalizowanych pod kątem pamięci metadanych bazy danych tempdb (HkTempDB) poza błędami pamięci.
- Jeśli urzędnik
Szybka ulga, która może udostępnić pamięć
Następujące akcje mogą zwolnić pamięć i udostępnić ją programowi SQL Server:
Zmienianie ustawień konfiguracji pamięci
Sprawdź następujące parametry konfiguracji pamięci programu SQL Server i rozważ zwiększenie maksymalnej pamięci serwera, jeśli to możliwe:
- maksymalna pamięć serwera
- minimalna pamięć serwera
Uwaga 16.
Jeśli zauważysz nietypowe ustawienia, popraw je w razie potrzeby i uwzględnij zwiększone wymagania dotyczące pamięci. Ustawienia domyślne są wyświetlane w opcjach konfiguracji pamięci serwera.
Jeśli nie skonfigurowano maksymalnej pamięci serwera, zwłaszcza w przypadku zablokowanych stron w pamięci, rozważ ustawienie jej na określoną wartość, aby umożliwić korzystanie z pamięci systemu operacyjnego. Zobacz opcję Konfiguracja zablokowanych stron w konfiguracji serwera pamięci.
Zmienianie lub przenoszenie obciążenia z systemu
Zbadaj obciążenie zapytania: liczba równoczesnych sesji, aktualnie wykonywanych zapytań i sprawdź, czy istnieją mniej krytyczne aplikacje, które mogą zostać tymczasowo zatrzymane lub przeniesione do innego programu SQL Server.
W przypadku obciążeń tylko do odczytu rozważ przeniesienie ich do repliki pomocniczej tylko do odczytu w środowisku Always On. Aby uzyskać więcej informacji, zobacz Odciążanie obciążenia tylko do odczytu do pomocniczej repliki zawsze włączonej grupy dostępności i Konfigurowanie dostępu tylko do odczytu do repliki pomocniczej zawsze włączonej grupy dostępności.
Zapewnianie prawidłowej konfiguracji pamięci dla maszyn wirtualnych
Jeśli używasz programu SQL Server na maszynie wirtualnej, upewnij się, że pamięć maszyny wirtualnej nie jest nadmiernie zatwierdzana. Aby zapoznać się z pomysłami dotyczącymi konfigurowania pamięci dla maszyn wirtualnych, zobacz Wirtualizacja — nadmierna alokacja pamięci i sposób wykrywania jej na maszynie wirtualnej oraz Rozwiązywanie problemów z wydajnością maszyn wirtualnych ESX/ESXi (nadmierna alokacja pamięci).
Zwolnij pamięć wewnątrz programu SQL Server
Możesz uruchomić co najmniej jedno z następujących poleceń DBCC, aby zwolnić kilka pamięci podręcznych programu SQL Server:
DBCC FREESYSTEMCACHE
DBCC FREESESSIONCACHE
DBCC FREEPROCCACHE
Uruchom ponownie usługę PROGRAMU SQL Server
W niektórych przypadkach, jeśli musisz poradzić sobie z krytycznym wyczerpaniem pamięci, a program SQL Server nie może przetworzyć zapytań, możesz rozważyć ponowne uruchomienie usługi.
Rozważ użycie zarządcy zasobów w określonych scenariuszach
Jeśli używasz zarządcy zasobów, zalecamy sprawdzenie ustawień puli zasobów i grupy obciążeń, aby sprawdzić, czy nie ograniczają one zbyt drastycznie pamięci.
Dodawanie większej ilości pamięci RAM na serwerze fizycznym lub wirtualnym
Jeśli problem będzie się powtarzać, należy dokładniej zbadać i ewentualnie zwiększyć zasoby serwera (RAM).