Problemen met onvoldoende geheugen of weinig geheugen in SQL Server oplossen
Symptomen
SQL Server maakt gebruik van een complexe geheugenarchitectuur die overeenkomt met de complexe en uitgebreide functieset. Vanwege de verscheidenheid aan geheugenbehoeften kunnen er veel bronnen van geheugenverbruik en geheugendruk zijn, waardoor uiteindelijk geheugenomstandigheden ontstaan.
Er zijn veelvoorkomende fouten die duiden op weinig geheugen in SQL Server. Voorbeelden van fouten zijn:
- 701: Kan onvoldoende geheugen toewijzen om een query uit te voeren.
- 802: Kan geen geheugen ophalen voor het toewijzen van pagina's in de buffergroep (gegevens- of indexpagina's).
- 1204: Kan geen geheugen toewijzen voor vergrendelingen.
- 6322: Kan geen geheugen toewijzen voor XML-parser.
- 6513:Kan CLR niet initialiseren vanwege geheugendruk.
- 6533: AppDomain is niet geladen vanwege onvoldoende geheugen.
- 8318: Kan SQL-prestatiemeteritems niet laden vanwege onvoldoende geheugen.
- 8356 of 8359: ETW of SQL-tracering kan niet worden uitgevoerd vanwege onvoldoende geheugen.
- 8556: Kan MSDTC niet laden vanwege onvoldoende geheugen.
- 8645: Fout bij het uitvoeren van een query vanwege geen geheugen voor geheugentoekenningen (sorteren en hashen) Zie Sql Server-fout 8645 oplossen voor meer informatie.
- 8902: Kan geen geheugen toewijzen tijdens de uitvoering van DBCC.
- 9695 of 9696: Fout bij het toewijzen van geheugen voor Service Broker-bewerkingen.
- 17131 of 17132: Opstartfout server vanwege onvoldoende geheugen.
- 17890: Fout bij het toewijzen van geheugen omdat sql-geheugen door het besturingssysteem wordt gepaginad.
- 18053: De fout wordt afgedrukt in de terse-modus omdat er een fout is opgetreden tijdens de opmaak. Tracering, ETW, meldingen enzovoort worden overgeslagen.
- 22986 of 22987: Fouten bij het vastleggen van gegevens wijzigen vanwege onvoldoende geheugen.
- 25601: De Xevent-engine heeft onvoldoende geheugen.
- 26053: SQL-netwerkinterfaces kunnen niet worden geïnitialiseerd vanwege onvoldoende geheugen.
- 30085, 30086, 30094: SQL-bewerkingen in volledige tekst mislukken vanwege onvoldoende geheugen.
Oorzaak
Veel factoren kunnen onvoldoende geheugen veroorzaken. Dergelijke factoren omvatten besturingssysteeminstellingen, beschikbaarheid van fysiek geheugen, onderdelen die geheugen in SQL Server gebruiken en geheugenlimieten voor de huidige werkbelasting. In de meeste gevallen is de query die mislukt met een fout met onvoldoende geheugen niet de oorzaak van deze fout. Over het algemeen kunnen de oorzaken worden gegroepeerd in drie categorieën:
Oorzaak 1: Geheugendruk van extern of besturingssysteem
Externe druk verwijst naar een hoog geheugengebruik dat afkomstig is van een onderdeel buiten het proces dat leidt tot onvoldoende geheugen voor SQL Server. U moet nagaan of andere toepassingen op het systeem geheugen verbruiken en bijdragen aan een lage beschikbaarheid van geheugen. SQL Server is een van de weinige toepassingen die zijn ontworpen om te reageren op geheugendruk van het besturingssysteem door het geheugengebruik te verlagen. Dit betekent dat als een toepassing of stuurprogramma geheugen aanvraagt, het besturingssysteem een signaal verzendt naar alle toepassingen om geheugen vrij te maken en SQL Server reageert door het eigen geheugengebruik te verminderen. Enkele andere toepassingen reageren omdat ze niet zijn ontworpen om naar die melding te luisteren. Als SQL Server begint met het terugsnijden van het geheugengebruik, wordt de geheugengroep daarom verminderd en de onderdelen die geheugen nodig hebben, krijgen deze mogelijk niet. Als gevolg hiervan krijgt u 701 of andere geheugengerelateerde fouten. Zie SQL Server-geheugenarchitectuur voor meer informatie over hoe SQL dynamisch geheugen toewijst en vrijgeeft. Zie Externe geheugenbelasting in dit artikel voor meer gedetailleerde diagnostische gegevens en oplossingen voor het probleem.
Er zijn drie algemene categorieën problemen die geheugenbelasting van het besturingssysteem kunnen veroorzaken:
- Problemen met betrekking tot toepassingen: een of veel toepassingen samen gebruiken het beschikbare fysieke geheugen. Het besturingssysteem reageert op nieuwe toepassingsaanvragen voor resources door geheugen vrij te maken. De algemene aanpak is om te vinden welke toepassingen het geheugen uitputten en de benodigde stappen ondernemen om het geheugen onder hen te verdelen zonder dat dit tot RAM-uitputting leidt.
- Problemen met apparaatstuurprogramma's: apparaatstuurprogramma's kunnen ervoor zorgen dat alle processen worden gepagineerd als het stuurprogramma een geheugentoewijzingsfunctie onjuist aanroept.
- Problemen met het besturingssysteemproduct.
Raadpleeg MSSQLSERVER_17890 voor een gedetailleerde uitleg van deze en stappen voor probleemoplossing.
Oorzaak 2: Interne geheugenbelasting, niet afkomstig van SQL Server
Interne geheugenbelasting verwijst naar lage geheugen beschikbaarheid veroorzaakt door factoren in het SQL Server-proces. Sommige onderdelen die in het SQL Server-proces kunnen worden uitgevoerd, zijn 'extern' voor de SQL Server-engine. Voorbeelden hiervan zijn OLE DB-providers (DLL's), zoals gekoppelde servers, SQLCLR-procedures of -functies, uitgebreide procedures (XPs) en OLE Automation (sp_OA*
). Andere omvatten antivirusprogramma's of andere beveiligingsprogramma's die DLL's in een proces injecteren voor bewakingsdoeleinden. Een probleem of slecht ontwerp in een van deze onderdelen kan leiden tot een groot geheugenverbruik. Denk bijvoorbeeld aan een gekoppelde server die 20 miljoen rijen gegevens uit een externe bron in het cachegeheugen van SQL Server cachet. Wat SQL Server betreft, rapporteert geen geheugenbediende een hoog geheugengebruik, maar het geheugen dat in het SQL Server-proces wordt verbruikt, is hoog. Deze geheugengroei van een gekoppelde server-DLL leidt er bijvoorbeeld toe dat SQL Server het geheugengebruik (zie hierboven) knipt en dat er weinig geheugen voor onderdelen in SQL Server ontstaat, waardoor geheugenfouten optreden. Zie Interne geheugenbelasting, niet afkomstig van SQL Server, voor gedetailleerdere diagnostische gegevens en oplossingen voor het probleem.
Notitie
Een paar Microsoft-DLL's die worden gebruikt in de SQL Server-procesruimte (bijvoorbeeld MSOLEDBSQL, SQL Native Client) kunnen interfacen met de SQL Server-geheugeninfrastructuur voor rapportage en toewijzing. U kunt deze uitvoeren select * from sys.dm_os_memory_clerks where type='MEMORYCLERK_HOST'
om een lijst met deze gegevens op te halen en het geheugenverbruik voor sommige van hun toewijzingen bij te houden.
Oorzaak 3: Interne geheugenbelasting afkomstig van SQL Server-onderdelen
Interne geheugenbelasting die afkomstig is van onderdelen in de SQL Server-engine kan ook leiden tot geheugenfouten. Er zijn honderden onderdelen bijgehouden via geheugenbediendeks die geheugen toewijzen in SQL Server. U moet bepalen welke geheugenbediende(s) verantwoordelijk zijn voor de grootste geheugentoewijzingen om dit probleem op te lossen. Als u bijvoorbeeld merkt dat de OBJECTSTORE_LOCK_MANAGER
geheugenbediende een grote geheugentoewijzing weergeeft, moet u begrijpen waarom lock manager zoveel geheugen verbruikt. Er zijn mogelijk query's die veel vergrendelingen verkrijgen. U kunt deze query's optimaliseren met behulp van indexen, het verkorten van transacties die lange tijd vergrendelingen bevatten of controleren of escalatie van vergrendelingen is uitgeschakeld. Elke geheugenbediende of elk onderdeel heeft een unieke manier om toegang te krijgen tot en het gebruik van geheugen. Zie geheugenbediende typen en hun beschrijvingen voor meer informatie. Zie Intern geheugengebruik door de SQL Server-engine voor gedetailleerdere diagnostische gegevens en oplossingen voor het probleem.
Visuele weergave van de geheugendruktypen
In de volgende grafiek ziet u de typen druk die kan leiden tot onvoldoende geheugen in SQL Server:
Diagnostische hulpprogramma's voor het verzamelen van probleemoplossingsgegevens
U kunt de volgende diagnostische hulpprogramma's gebruiken om probleemoplossingsgegevens te verzamelen:
Prestatiemeter
Configureer en verzamel de volgende tellers met Prestatiemeter:
- Geheugen:Beschikbare MBytes
- Proces:Werkset
- Proces: privébytes
- SQL Server:Memory Manager: (alle tellers)
- SQL Server:Bufferbeheer: (alle tellers)
DMV's of DBCC MEMORYSTATUS
U kunt sys.dm_os_memory_clerks of DBCC MEMORYSTATUS gebruiken om het totale geheugengebruik in SQL Server te observeren.
Standaardrapport geheugenverbruik in SSMS
Geheugengebruik weergeven in SQL Server Management Studio:
- Start SQL Server Management Studio en maak verbinding met een server.
- Klik in Objectverkenner met de rechtermuisknop op de naam van het SQL Server-exemplaar.
- Selecteer >in het contextmenu Rapporten standaardrapporten>geheugenverbruik.
PSSDiag of SQL LogScout
Een alternatieve, geautomatiseerde manier om deze gegevenspunten vast te leggen, is door hulpprogramma's zoals PSSDiag of SQL LogScout te gebruiken.
Als u PSSDiag gebruikt, configureert u deze om de Perfmon-collector en de Collector Custom Diagnostics\SQL Memory Error vast te leggen.
Als u SQL LogScout gebruikt, configureert u deze om het geheugenscenario vast te leggen.
In de volgende secties worden gedetailleerdere stappen beschreven voor elk scenario (externe of interne geheugenbelasting).
Methodologie voor probleemoplossing
Als er af en toe een fout met onvoldoende geheugen wordt weergegeven of gedurende een korte periode, is er mogelijk een probleem met een kortstondig geheugen dat zichzelf oplost. Mogelijk hoeft u in deze gevallen geen actie te ondernemen. Als de fout echter meerdere keren optreedt op meerdere verbindingen en zich gedurende seconden of langer blijft voordoen, volgt u de diagnostische gegevens en oplossingen in de volgende secties om geheugenfouten verder op te lossen.
Druk op extern geheugen
Gebruik de volgende methoden om problemen met weinig geheugen op het systeem buiten het SQL Server-proces te diagnosticeren:
Prestatiemeteritems verzamelen. Onderzoek of toepassingen of services anders dan SQL Server geheugen op deze server verbruiken door deze tellers te bekijken:
- Geheugen:Beschikbare MBytes
- Proces:Werkset
- Proces: privébytes
Hier volgt een voorbeeld van het verzamelen van Perfmon-logboeken met behulp van 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)) } } }
Bekijk het systeemgebeurtenislogboek en zoek naar geheugengerelateerde fouten (zoals weinig virtueel geheugen).
Controleer het toepassingsgebeurtenislogboek op toepassingsgerelateerde geheugenproblemen.
Hier volgt een voorbeeld van een PowerShell-script om een query uit te voeren op de systeem- en toepassingslogboeken voor het trefwoord 'geheugen'. U kunt gerust andere tekenreeksen zoals 'resource' gebruiken voor uw zoekopdracht:
Get-EventLog System -ComputerName "$env:COMPUTERNAME" -Message "*memory*" Get-EventLog Application -ComputerName "$env:COMPUTERNAME" -Message "*memory*"
Los eventuele code- of configuratieproblemen op voor minder kritieke toepassingen of services om het geheugengebruik te verminderen.
Als toepassingen naast SQL Server resources verbruiken, kunt u deze toepassingen stoppen of opnieuw plannen, of overwegen ze uit te voeren op een afzonderlijke server. Met deze stappen wordt de druk van het externe geheugen verwijderd.
Interne geheugenbelasting, niet afkomstig van SQL Server
Gebruik de volgende methoden om interne geheugenbelasting te diagnosticeren die wordt veroorzaakt door modules (DLL's) in SQL Server:
Als SQL Server geen vergrendelde pagina's in het geheugen (AWE API) gebruikt, wordt het grootste deel van het geheugen weergegeven in het prestatiemeteritem Process:Private Bytes (
SQLServr
instance). Het totale geheugengebruik dat afkomstig is van de SQL Server-engine, wordt weergegeven in de teller SQL Server:Memory Manager: Total Server Memory (KB). Als u een belangrijk verschil vindt tussen het waardeproces : privébytes en SQL Server:Memory Manager: Totaal servergeheugen (KB) komt dat verschil waarschijnlijk uit een DLL (gekoppelde server, XP, SQLCLR, enzovoort). Als privébytes bijvoorbeeld 300 GB zijn en het totale servergeheugen 250 GB is, is ongeveer 50 GB van het totale geheugen in het proces afkomstig van buiten de SQL Server-engine.Als SQL Server vergrendelde pagina's in het geheugen (AWE-API) gebruikt, is het lastiger om het probleem te identificeren omdat de prestatiemeter geen AWE-tellers biedt waarmee het geheugengebruik voor afzonderlijke processen wordt bijgehouden. Het totale geheugengebruik in de SQL Server-engine wordt weerspiegeld in de teller SQL Server:Memory Manager: Total Server Memory (KB). Typische waarden voor proces:privébytes kunnen variëren tussen 300 MB en 1-2 GB in totaal. Als u een aanzienlijk gebruik vindt van Proces:Privébytes buiten dit typische gebruik, is het verschil waarschijnlijk afkomstig van een DLL (gekoppelde server, XP, SQLCLR, enzovoort). Als het teller voor privébytes bijvoorbeeld 4-5 GB is en SQL Server vergrendelde pagina's in het geheugen (AWE) gebruikt, kan een groot deel van de privébytes afkomstig zijn van buiten de SQL Server-engine. Dit is een benaderingstechniek.
Gebruik het hulpprogramma Tasklist om dll's te identificeren die in de SQL Server-ruimte worden geladen:
tasklist /M /FI "IMAGENAME eq sqlservr.exe"
U kunt ook de volgende query gebruiken om geladen modules (DLL's) te onderzoeken en te zien of er iets onverwachts is.
SELECT * FROM sys.dm_os_loaded_modules
Als u vermoedt dat een gekoppelde servermodule een aanzienlijk geheugenverbruik veroorzaakt, kunt u deze zo configureren dat deze niet meer kan worden verwerkt door de optie Inprocess toestaan uit te schakelen. Zie Gekoppelde servers maken voor meer informatie. Niet alle OLE DB-providers voor gekoppelde servers kunnen niet meer worden verwerkt. Neem voor meer informatie contact op met de fabrikant van het product.
In het zeldzame geval waarin OLE-automatiseringsobjecten (
sp_OA*
) worden gebruikt, kunt u het object zo configureren dat het wordt uitgevoerd in een proces buiten SQL Server door alleen een contextwaarde van 4 (lokaal (.exe) OLE-server op te geven. Zie sp_OACreate voor meer informatie.
Intern geheugengebruik door SQL Server-engine
Gebruik de volgende methoden om een diagnose te stellen van interne geheugenbelasting die afkomstig is van onderdelen in de SQL Server-engine:
Begin met het verzamelen van prestatiemeteritems voor SQL Server: SQL Server:Bufferbeheer en SQL Server: Memory Manager.
Voer meerdere keren een query uit op de SQL Server-geheugenmedewerkers DMV om te zien waar het hoogste geheugenverbruik plaatsvindt in de engine:
SELECT pages_kb, type, name, virtual_memory_committed_kb, awe_allocated_kb FROM sys.dm_os_memory_clerks ORDER BY pages_kb DESC
U kunt ook de gedetailleerdere
DBCC MEMORYSTATUS
uitvoer bekijken en de manier waarop deze wordt gewijzigd wanneer u deze foutberichten ziet.DBCC MEMORYSTATUS
Als u een duidelijke dader onder de geheugenbedienden identificeert, moet u zich richten op de specifieke kenmerken van het geheugenverbruik voor dat onderdeel. Hier volgen enkele voorbeelden:
- Als de geheugenbediende
MEMORYCLERK_SQLQERESERVATIONS
geheugen geheugen verbruikt, identificeert u query's die gebruikmaken van enorme geheugentoekenningen en optimaliseert u deze via indexen, herschrijft u deze (bijvoorbeeld verwijderenORDER by
) of past u hints voor geheugentoekenningen toe (zie min_grant_percent en max_grant_percent hints ). U kunt ook een resource governor-pool maken om het gebruik van geheugentoe kennen te beheren. Zie Problemen met trage prestaties of weinig geheugen oplossen die worden veroorzaakt door geheugentoelagen in SQL Server voor gedetailleerde informatie over geheugentoelagen. - Als een groot aantal ad-hocqueryplannen in de cache wordt opgeslagen, zou de
CACHESTORE_SQLCP
geheugenbediende grote hoeveelheden geheugen gebruiken. Identificeer niet-geparameteriseerde query's waarvan queryplannen niet opnieuw kunnen worden gebruikt en parameteriseren door ze te converteren naar opgeslagen procedures, met behulp vansp_executesql
of met behulp vanFORCED
parameterisatie. Als u traceringsvlag 174 hebt ingeschakeld, kunt u deze uitschakelen om te zien of dit het probleem oplost. - Als het cachearchief
CACHESTORE_OBJCP
van het objectplan te veel geheugen verbruikt, identificeert u welke opgeslagen procedures, functies of triggers grote hoeveelheden geheugen gebruiken en ontwerpt u de toepassing mogelijk opnieuw. Dit kan meestal gebeuren als gevolg van grote hoeveelheden databases of schema's met honderden procedures in elk. - Als de
OBJECTSTORE_LOCK_MANAGER
geheugenbediende grote geheugentoewijzingen weergeeft, identificeert u query's die veel vergrendelingen toepassen en optimaliseren met behulp van indexen. Verkort transacties die ertoe leiden dat vergrendelingen niet worden vrijgegeven voor lange perioden in bepaalde isolatieniveaus of controleer of escalatie van vergrendelingen is uitgeschakeld. - Als u zeer groot
TokenAndPermUserStore
(select type, name, pages_kb from sys.dm_os_memory_clerks where name = 'TokenAndPermUserStore'
) ziet, kunt u traceringsvlag 4618 gebruiken om de grootte van de cache te beperken. - Als u geheugenproblemen met OLTP in het geheugen ziet die afkomstig zijn van de
MEMORYCLERK_XTP
geheugenbediende, kunt u het geheugengebruik voor in-memory OLTP- en tempdb-metagegevens (HkTempDB) uit geheugenfouten raadplegen en problemen oplossen met geheugengebruik.
- Als de geheugenbediende
Snelle opluchting die geheugen beschikbaar kan maken
De volgende acties kunnen geheugen vrijmaken en beschikbaar maken voor SQL Server:
Instellingen voor geheugenconfiguratie wijzigen
Controleer de volgende sql Server-geheugenconfiguratieparameters en overweeg indien mogelijk het maximale servergeheugen te verhogen:
- maximaal servergeheugen
- minimale servergeheugen
Notitie
Als u ongebruikelijke instellingen ziet, corrigeert u deze indien nodig en houdt u rekening met verhoogde geheugenvereisten. Standaardinstellingen worden vermeld in opties voor servergeheugenconfiguratie.
Als u het maximale servergeheugen niet hebt geconfigureerd, met name met vergrendelde pagina's in het geheugen, kunt u overwegen deze in te stellen op een bepaalde waarde om geheugen toe te staan voor het besturingssysteem. Zie de optie Vergrendelde pagina's in de configuratieoptie Geheugenserver .
Werkbelasting van het systeem wijzigen of verplaatsen
Onderzoek de queryworkload: het aantal gelijktijdige sessies, momenteel uitgevoerde query's en kijk of er minder kritieke toepassingen zijn die tijdelijk kunnen worden gestopt of naar een andere SQL Server kunnen worden verplaatst.
Voor alleen-lezenwerkbelastingen kunt u deze verplaatsen naar een alleen-lezen secundaire replica in een AlwaysOn-omgeving. Zie Alleen-lezen workload offloaden naar secundaire replica van een AlwaysOn-beschikbaarheidsgroep en Alleen-lezentoegang configureren tot een secundaire replica van een AlwaysOn-beschikbaarheidsgroep voor meer informatie.
De juiste geheugenconfiguratie voor virtuele machines garanderen
Als u SQL Server uitvoert op een virtuele machine (VM), moet u ervoor zorgen dat het geheugen voor de VIRTUELE machine niet wordt overgecommitteerd. Zie Virtualization - Overcommitting memory and how to detect it within the VM and Troubleshooting ESX/ESXi virtual machine performance issues (memory overcommitment)voor ideeën over het configureren van geheugen voor VM's.
Geheugen vrijgeven in SQL Server
U kunt een of meer van de volgende DBCC-opdrachten uitvoeren om verschillende SQL Server-geheugencaches leeg te maken:
DBCC FREESYSTEMCACHE
DBCC FREESESSIONCACHE
DBCC FREEPROCCACHE
SQL Server-service opnieuw starten
In sommige gevallen kunt u overwegen om de service opnieuw te starten als u te maken hebt met kritieke uitputting van het geheugen en SQL Server geen query's kan verwerken.
Overweeg resource governor te gebruiken voor specifieke scenario's
Als u Resource Governor gebruikt, raden we u aan om de instellingen van de resourcegroep en workloadgroep te controleren om te zien of ze het geheugen niet te drastisch beperken.
Meer RAM toevoegen op de fysieke of virtuele server
Als het probleem zich blijft voordoen, moet u verder onderzoeken en mogelijk serverbronnen (RAM) verhogen.