Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Sammanfattning
Den här artikeln beskriver hur du felsöker minnesproblem i SQL Server, inklusive fel vid slut på minne och fel vid minnesallokering, situationer med ont om minne och relaterade prestandaproblem. Det förklarar symptomen, de tre huvudsakliga kategorierna av minnestryck (externt, internt från icke-motormoduler och interna från SQL Server motorkomponenter), diagnostikverktygen som du kan använda för att samla in data och de steg du kan vidta för att åtgärda eller minska minnesbelastningen på en SQL Server instans.
Symptom på fel på grund av för lite minne
SQL Server använder en komplex minnesarkitektur som motsvarar den komplexa och omfattande funktionsuppsättningen. På grund av de olika minnesbehoven kan många källor orsaka minnesförbrukning och minnestryck, vilket kan leda till minnesbrist.
Vanliga fel tyder på att det finns ont om minne i SQL Server. Exempel på dessa fel är:
- 701: Det gick inte att allokera tillräckligt med minne för att köra en fråga.
- 802: Det gick inte att hämta minne för att allokera sidor i buffertpoolen (data eller indexsidor).
- 1204: Det gick inte att allokera minne för lås.
- 6322: Det gick inte att allokera minne för XML-parser.
- 6513: Det gick inte att initiera CLR på grund av minnesbrist.
- 6533: AppDomain har avladdats på grund av minnesbrist.
- 8318: Det gick inte att läsa in SQL-prestandaräknare på grund av otillräckligt minne.
- 8356 eller 8359: ETW- eller SQL-spårningen kan inte köras på grund av lite minne.
- 8556: Det gick inte att läsa in MSDTC på grund av otillräckligt minne.
- 8645: Det gick inte att köra frågan på grund av otillräckligt minne för minnestilldelning (sortering och hashning).
- 8902: Det gick inte att allokera minne under DBCC-körningen.
- 9695 eller 9696: Det gick inte att allokera minne för Service Broker-åtgärder.
- 17131 eller 17132: Serverstartfel på grund av otillräckligt minne.
- 17890: Det gick inte att allokera minne på grund av att SQL-minnet har bläddrats ut av operativsystemet.
- 18053: Felet skrivs ut i terse-läge eftersom det uppstod ett fel under formateringen. Spårning, ETW och meddelanden utelämnas.
- 22986 eller 22987: Ändra datainsamlingsfel på grund av otillräckligt minne.
- 25601: Xevent-motorn har slut på minne.
- 26053: SQL-nätverksgränssnitten kan inte initieras på grund av otillräckligt minne.
- 30085, 30086, 30094: SQL-fulltextåtgärder misslyckas på grund av otillräckligt minne.
Orsak till problem med lite minne
Många faktorer kan orsaka otillräckligt minne. Sådana faktorer omfattar operativsysteminställningar, tillgänglighet för fysiskt minne, komponenter som använder minne i SQL Server och minnesgränser för den aktuella arbetsbelastningen. I de flesta fall är frågan som misslyckas med ett out-of-memory-fel inte orsaken till felet. Du kan gruppera orsakerna i tre kategorier.
Externt eller OS-minnestryck
Externt tryck avser hög minnesanvändning från en komponent utanför SQL Server process som leder till otillräckligt minne för SQL Server. Kontrollera om andra program i systemet förbrukar minne och bidrar till låg minnestillgänglighet. SQL Server är ett av de få program som är utformade för att svara på os-minnesbelastning genom att minska minnesanvändningen. Om ett program eller en drivrutin begär minne skickar operativsystemet en signal till alla program för att frigöra minne och SQL Server svarar genom att minska sin egen minnesanvändning. Få andra program svarar eftersom de inte är utformade för att lyssna efter meddelandet. När SQL Server minskar minnesanvändningen krymper minnespoolen och komponenter som behöver minne kanske inte får det. Därför börjar du få 701 eller andra minnesrelaterade fel. Mer information om hur SQL Server dynamiskt allokerar och frigör minne finns i SQL Server minnesarkitektur. Detaljerad diagnostik och lösningar finns i Externt minnestryck i den här artikeln.
Tre breda kategorier av problem kan orsaka minnestryck i operativsystemet:
- Programrelaterade problem: Ett eller flera program uttömmer tillsammans det tillgängliga fysiska minnet. Operativsystemet svarar på nya programbegäranden för resurser genom att försöka frigöra lite minne. Ta reda på vilka program som överbelastar minnet och vidta åtgärder för att balansera minne mellan dem utan att överbelasta RAM-minnet.
- Problem med enhetsdrivrutiner: Enhetsdrivrutiner kan orsaka arbetsuppsättningsväxling för alla processer om en drivrutin felaktigt anropar en minnesallokeringsfunktion.
- Produktproblem för operativsystem.
En detaljerad förklaring och felsökningssteg finns i MSSQLSERVER_17890.
Internt minnestryck från moduler som inte är motoriska
Internt minnestryck avser låg minnestillgänglighet som orsakas av faktorer i SQL Server-processen. Vissa komponenter som körs i SQL Server processen är external till SQL Server-motorn. Exempel är OLE DB-providers (DLL:er) som länkade servrar, SQLCLR-procedurer eller funktioner, utökade procedurer (XPs) och OLE Automation (sp_OA*). Andra inkluderar antivirus- eller säkerhetsprogram som matar in DLL:er i processen i övervakningssyfte. Ett problem eller dålig design i någon av dessa komponenter kan leda till stor minnesförbrukning. Tänk dig till exempel att en länkad server cachelagr 20 miljoner rader data från en extern källa till SQL Server-minne. Från motorns perspektiv rapporterar ingen minnestjänsteman hög minnesanvändning, men minnet som förbrukas i SQL Server processen är högt. Den här minnestillväxten från en länkad server-DLL gör att SQL Server börjar minska minnesanvändningen och skapar låga minnesförhållanden för motorkomponenter, vilket leder till minnesfel. Detaljerad diagnostik och lösningar finns i Internt minnestryck från moduler som inte är motorer.
Kommentar
Några Microsoft DLL:er som används i SQL Server processutrymme (till exempel MSOLEDBSQL och SQL Server intern klient) kan samverka med SQL Server minnesinfrastruktur för rapportering och allokering. Kör SELECT * FROM sys.dm_os_memory_clerks WHERE type='MEMORYCLERK_HOST' för att hämta en lista över dem och spåra minnesförbrukning för vissa av deras allokeringar. SQL Server intern klient (SNAC) är inaktuell. Ny utveckling bör använda MSOLEDBSQL eller Microsoft ODBC-drivrutin för SQL Server.
Internt minnestryck från SQL Server motorkomponenter
Internt minnestryck från komponenter i SQL Server-motorn kan också leda till minnesfel. Hundratals komponenter som spåras via memory clerks allokera minne i SQL Server. Identifiera vilka memory clerks som ansvarar för de största allokeringarna för att lösa problemet. Om till exempel memory clerk OBJECTSTORE_LOCK_MANAGER visar en stor allokering, tar du reda på varför Lock Manager förbrukar så mycket minne. Du kan upptäcka frågor som tar många lås. Optimera dessa frågor med hjälp av index, genom att förkorta transaktioner som håller lås under en längre tid eller genom att kontrollera om låseskalering är inaktiverat. Varje minnestjänsteman eller komponent har ett unikt sätt att använda minne. Mer information finns i sys.dm_os_memory_clerks och beskrivningar av typen minnestjänsteman. Detaljerad diagnostik och lösningar finns i Internal minnesanvändning av SQL Server-motorn.
Minnestryckstyper
I följande diagram visas de typer av tryck som kan leda till minnesbrist i SQL Server:
Diagnostikverktyg för att felsöka minnesproblem
Använd följande diagnostikverktyg för att samla in felsökningsdata.
Prestandaövervakaren
Konfigurera och samla in följande räknare med hjälp av Performance Monitor:
- Minne:Tillgängliga MByte
- Process:Arbetsuppsättning
- Process:Private Bytes
- SQL Server:Memory Manager: (alla räknare)
- SQL Server:Buffer Manager: (alla räknare)
DMV:er och DBCC MEMORYSTATUS
Använd sys.dm_os_memory_clerks eller DBCC MEMORYSTATUS för att observera den totala minnesanvändningen i SQL Server.
sys.dm_os_memory_clerks returnerar en rad per minnestjänsteman och är den bästa utgångspunkten för att hitta vilka komponenter som förbrukar mest minne.
DBCC MEMORYSTATUS returnerar en mer detaljerad ögonblicksbild som grupperar information efter minneshanterare, buffertpool och kontorister.
Rapport om minnesförbrukning i SSMS
Så här visar du minnesanvändning i SQL Server Management Studio (SSMS):
- Öppna SSMS och anslut till en server.
- I Object Explorer trycker du och håller ned namnet på SQL Server-instansen (eller högerklickar på det).
- I snabbmenyn väljer du Rapporter>Standardrapporter>Minnesförbrukning.
PSSDiag eller SQL LogScout
Om du vill samla in dessa datapunkter automatiskt använder du ett verktyg som PSSDiag eller SQL LogScout.
- Om du använder PSSDiag konfigurerar du det för att samla in Perfmon-insamlaren och Anpassad diagnostik\SQL-minnesfel-insamlaren.
- Om du använder SQL LogScout konfigurerar du det för att avbilda minnesscenariot .
Snabb lättnad för att frigöra minne
Följande åtgärder kan frigöra lite minne och göra det tillgängligt för SQL Server. Använd dem som en tillfällig lösning medan du undersöker grundorsaken.
Ändra minneskonfiguration
Kontrollera följande parametrar för SQL Server-minneskonfiguration och överväg att öka maximalt serverminne om möjligt:
- maximalt serverminne
- minsta serverminne
Kommentar
Om du märker ovanliga inställningar korrigerar du dem efter behov och tar hänsyn till ökade minnesbehov. Standardinställningarna visas i Konfigurationsalternativ för serverminne.
Om du inte har angett maximalt serverminne, särskilt med Lås sidor i minnet aktiverat, anger du det till ett specifikt värde för att lämna minnet för operativsystemet. Mer information finns i alternativet Lås sidor i minnet (LPIM) serverkonfiguration.
Ändra eller flytta arbetsbelastningen
Granska frågearbetsbelastningen, inklusive antalet samtidiga sessioner och frågor som körs för närvarande. Kontrollera om du kan stoppa mindre kritiska program tillfälligt eller flytta dem till en annan SQL Server instans.
För skrivskyddade arbetsbelastningar bör du överväga att flytta dem till en skrivskyddad sekundär replik i en AlwaysOn-miljö. Mer information finns i Avlasta skrivskyddad arbetsbelastning till en sekundär replik av en AlwaysOn-tillgänglighetsgrupp och Konfigurera skrivskyddad åtkomst till en sekundär replik av en AlwaysOn-tillgänglighetsgrupp.
Kontrollera minneskonfigurationen för virtuella datorer
Om du kör SQL Server på en virtuell dator kontrollerar du att värden inte överskrider den virtuella datorns minne. Information om hur du ändrar storlek på minne för SQL Server på Azure virtuella datorer finns i Memory best practices for SQL Server på Azure Virtual Machines. För virtuella maskiner som körs på VMware finns information om hur du identifierar och undviker överallokering av minne i dokumentationen från din hypervisorleverantör.
Frigöra minne i SQL Server
Kör ett eller flera av följande DBCC-kommandon för att frigöra SQL Server minnescacheminnen. Använd dessa kommandon med försiktighet i produktionssystem eftersom de rensar cacheminnen som måste fyllas i igen:
DBCC FREESYSTEMCACHEDBCC FREESESSIONCACHEDBCC FREEPROCCACHE
Starta om SQL Server-tjänsten
Om minnesöverbelastning är kritiskt och SQL Server inte kan bearbeta frågor kan du starta om tjänsten som en sista utväg. Den här åtgärden tar bort alla aktiva anslutningar och rensar cacheminnen, så använd den bara när andra alternativ misslyckas.
Granska Resource Governor inställningar
Om du använder Resource Governor kontrollerar du inställningarna för resurspoolen och arbetsbelastningsgruppen för att se till att de inte begränsar minnet för drastiskt. Mer information finns i Resource Governor.
Lägg till mer RAM-minne
Om problemet kvarstår efter föregående steg undersöker du ytterligare och överväger att öka serverresurserna (RAM) på den fysiska eller virtuella servern.
Diagnostisera och åtgärda minnesbelastning
Om ett minnesbristfel bara uppstår ibland eller under en kort period kan problemet vara kortvarigt och gå över av sig självt, och då kan ingen åtgärd behövas. Om felet inträffar flera gånger i flera anslutningar och varar i flera sekunder eller längre följer du anvisningarna för diagnostik och lösning i följande avsnitt för att identifiera och åtgärda grundorsaken.
Externt minnestryck
Om du vill diagnostisera minnesbrist i systemet utanför SQL Server-processen använder du följande metoder:
Samla in prestandaövervakarräknare. Kontrollera om andra program eller tjänster än SQL Server förbrukar minne på den här servern genom att titta på dessa räknare:
- Minne:Tillgängliga MByte
- Process:Arbetsuppsättning
- Process:Private Bytes
Här är ett exempel på en Perfmon-loggsamling med 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)) } } }Granska systemhändelseloggen och leta efter minnesrelaterade fel (till exempel lite virtuellt minne).
Granska programhändelseloggen för programrelaterade minnesproblem.
Här är ett exempel på ett PowerShell-skript som frågar system- och programhändelseloggarna efter nyckelordet "minne". Du kan använda andra strängar som "resurs" för sökningen:
Get-EventLog System -ComputerName "$env:COMPUTERNAME" -Message "*memory*" Get-EventLog Application -ComputerName "$env:COMPUTERNAME" -Message "*memory*"Åtgärda eventuella kod- eller konfigurationsproblem för mindre kritiska program eller tjänster för att minska minnesanvändningen.
Om program förutom SQL Server förbrukar resurser kan du prova att stoppa eller schemalägga om dem eller köra dem på en separat server. De här stegen tar bort externt minnestryck.
Internt minnestryck från moduler som inte är motoriska
Använd följande metoder för att diagnostisera internt minnestryck som orsakas av moduler (DLL: er) i SQL Server:
Om SQL Server inte använder Lock Pages in Memory (AWE API) visas det mesta av minnesanvändningen i Process:Private Bytes räknaren (
sqlservrinstans) i Performance Monitor. Räknaren SQL Server:Memory Manager: Total Server Memory (KB) visar den totala minnesanvändningen inifrån SQL Server-motorn. Om du hittar en betydande skillnad mellan Process:Private Bytes och SQL Server:Memory Manager: Total Server Memory (KB), kommer den skillnaden sannolikt från en DLL (länkad server, XP, SQLCLR och så vidare). Om till exempel Private Bytes är 300 GB och Totalt serverminne är 250 GB, kommer cirka 50 GB av det totala minnet i processen utanför SQL Server motorn.Om SQL Server använder AWE-API (Lock Pages in Memory) är det svårare att identifiera problemet eftersom Performance Monitor inte erbjuder AWE-räknare som spårar minnesanvändning för enskilda processer. Räknaren SQL Server:Memory Manager: Total Server Memory (KB) visar den totala minnesanvändningen i SQL Server-motorn. Typiska värden för process:Privata byte kan variera mellan 300 MB och 1–2 GB totalt. Om Process:Private Bytes är betydligt högre än det här vanliga intervallet kommer skillnaden troligen från en DLL (länkad server, XP, SQLCLR och så vidare). Om till exempel Private Bytes är 4–5 GB och SQL Server använder låssidor i minnet (AWE), kan en stor del av Private Bytes komma utanför SQL Server motorn. Det här värdet är en uppskattning.
Använd verktyget
tasklistför att identifiera DLL:er som lästs in i SQL Server processen.tasklist /M /FI "IMAGENAME eq sqlservr.exe"Du kan också använda följande fråga för att undersöka inlästa moduler (DLL: er) och kontrollera om något oväntat finns:
SELECT * FROM sys.dm_os_loaded_modulesOm du misstänker att en länkad servermodul orsakar betydande minnesförbrukning konfigurerar du den så att processen tar slut genom att avmarkera alternativet Tillåt inprocess . Mer information finns i Skapa länkade servrar. Inte alla OLE DB-providers för länkade servrar kan köras utanför processen. Kontakta providertillverkaren om du vill ha mer information.
I sällsynta fall där OLE Automation-objekt (
sp_OA*) används kan du konfigurera objektet så att det körs i en process utanför SQL Server genom att ange ett kontextvärde för 4 (endast lokal (.exe) OLE-server). Mer information finns isp_OACreate.
Intern minnesanvändning av SQL Server-motorn
Använd följande metoder för att diagnostisera internt minnestryck från komponenter i SQL Server-motorn:
Börja samla in Performance Monitor räknare för SQL Server: SQL Server:Buffer Manager och SQL Server:Memory Manager.
Kör fråga mot DMV:n för SQL Servers memory clerks flera gånger för att se var minnesförbrukningen är som störst i databasmotorn.
SELECT pages_kb, type, name, virtual_memory_committed_kb, awe_allocated_kb FROM sys.dm_os_memory_clerks ORDER BY pages_kb DESCAlternativt kan du observera de mer detaljerade utdata som
DBCC MEMORYSTATUSger och hur de ändras när de här felmeddelandena visas.DBCC MEMORYSTATUSOm du identifierar en tydlig gärningsman bland minnesbiträdena fokuserar du på detaljerna i minnesförbrukningen för den komponenten. Här är några exempel:
- Om
MEMORYCLERK_SQLQERESERVATIONSmemory clerk förbrukar minne identifierar du frågor som använder stora minnestilldelningar och optimerar dem med index, genom att skriva om dem (till exempel genom att ta bortORDER BY) eller genom att använda frågetips för minnestilldelning (MIN_GRANT_PERCENTochMAX_GRANT_PERCENT). Mer information finns i Frågetips. Du kan också skapa en resurspool för att styra användningen av minnesbidrag. Mer information om minnesbidrag finns i Felsöka långsamma prestanda eller problem med låg minnesanvändning som orsakas av minnesbidrag i SQL Server. - Om många ad hoc-frågeplaner lagras i cacheminnet använder
CACHESTORE_SQLCPmemory clerk stora mängder minne. Identifiera frågor utan parametrar vars planer inte kan återanvändas och parameterisera dem genom att konvertera dem till lagrade procedurer, genom att användasp_executesql, eller genom att använda parameterisering medFORCED. Om spårningsflagga 174 är aktiverad kan du inaktivera den för att se om det löser problemet. - Om cachelagret
CACHESTORE_OBJCPför objektplan förbrukar för mycket minne kan du identifiera vilka lagrade procedurer, funktioner eller utlösare som använder stora mängder minne och överväg att göra om programmet. Detta händer ofta med många databaser eller scheman som var och en innehåller hundratals procedurer. - Om memory clerk
OBJECTSTORE_LOCK_MANAGERvisar stora allokeringar, identifiera de frågor som orsakar många låsningar och optimera dem med hjälp av index. Korta ned transaktioner som håller lås under lång tid vid vissa isoleringsnivåer, eller kontrollera om låseskalering är inaktiverad. - Om du ser en mycket stor
TokenAndPermUserStore(SELECT type, name, pages_kb FROM sys.dm_os_memory_clerks WHERE name = 'TokenAndPermUserStore') kan du använda spårningsflagga 4618 för att begränsa cachestorleken. - Om du observerar minnesproblem med In-Memory OLTP från
MEMORYCLERK_XTPminneshanteraren läser du Övervaka och felsöka minnesanvändning för In-Memory OLTP och Slut-på-minnet-fel för minnesoptimerade tempdb-metadata (HkTempDB).
- Om
Vanliga frågor och svar
Varför använder SQL Server nästan allt RAM-minne på servern?
SQL Server-buffertpoolen är avsedd att växa för att lagra datasidor i cacheminnet och minska fysisk I/O, så minnesanvändningen i stabilt läge närmar sig ofta inställningen max server memory. Det här beteendet är förväntat och är inte en läcka. Om du vill begränsa förbrukningen och lämna utrymme för operativsystemet och andra processer konfigurerar du maximalt serverminne. Mer information finns i Konfigurationsalternativ för serverminne.
Vad är skillnaden mellan maximalt serverminne och det incheckade minnet som visas i Aktivitetshanteraren?
Inställningen max server memory begränsar hur mycket minne som SQL Servers buffertpool och de flesta minneshanterare i databasmotorn kan allokera. Aktivitetshanteraren visar det incheckade minnet för hela sqlservr.exe processen. Den här vyn innehåller allokeringar som komponenter gör utanför buffertpoolen, till exempel CLR, länkade serverprovidrar, utökade lagrade procedurer och säkerhetskopieringsbuffertar. Därför kan det totala processminnet överskrida maximalt serverminne. Mer information finns i Arkitekturguide för minneshantering.
När ska jag aktivera Lås sidor i minnet (LPIM)?
Aktivera Lås sidor i minnet när OS trimmar SQL Servers arbetsminne. Det här problemet uppstår som fel 17890 eller plötsligt sjunker i totalt serverminne. Parkoppla LPIM med ett explicit maxvärde för serverminne för att lämna RAM-minne för operativsystemet och andra processer. Aktivera inte LPIM som standard för varje instans. Använd den för att åtgärda ett bekräftat personsökningsproblem.
Vad berättar sys.dm_os_memory_clerks för mig?
sys.dm_os_memory_clerks returnerar en rad för varje aktiv memory clerk i SQL Server-motorn samt hur mycket minne den allokerar. Använd den för att hitta vilken komponent (till exempel buffertpool, plancache, låshanterare eller frågeminnesbidrag) som förbrukar mest minne och för att styra justeringsarbetet.