sql >> Database teknologi >  >> RDS >> Sqlserver

Forstå vigtigheden af ​​hukommelsesindstilling i SQL Server

Hukommelse er en af ​​de ressourcer, der danner ydeevnetrekanten - CPU og lager er de to andre. Hvis den ene bliver ramt, tager de to andre belastningen for at prøve at bringe ydeevnen til acceptable niveauer, men der er altid en afvejning. Uanset hvilke transaktioner der ikke kan forpligtes til hukommelsen, vil de blive videresendt til diskundersystemet af SQL Server. Dette forårsager en flaskehals i ydeevnen. Derfor kan ventestatistikken hjælpe med at identificere ydeevneproblemer på en SQL Server.

I denne artikel diskuteres følgende emner:

  1. Forståelse af interne funktioner i SQL Server-hukommelsesindstilling og -konfiguration
  2. SQL Server-hukommelsen og dens indvirkning på databasen og applikationens ydeevne
  3. Diskuter forskellige SQL Server-komponenter, der bidrager til hukommelsesforbruget
  4. Bedste fremgangsmåder og anbefalinger til hukommelsesstørrelse
  5. Multi-server hukommelsesrapport
  6. Og mere...

Indbygget hukommelsesstyring

SQL Server har en Memory Management Unit, der udfører automatiseret dynamisk hukommelsesstyring baseret på systemets arbejdsbyrde. Denne hukommelse er det flygtige rum, der er afgørende for nutidens Business – Tech-behov, hvis rigtige størrelse er afgørende for den optimale ydeevne af applikationerne.

Vi ved dog alle, at når du opsætter serveren, indeholder størrelsen nogle standardværdier. i nogle tilfælde finder vi hurtigt ud af, at SQL Server bruger næsten al hukommelsen på serveren, selvom der ikke er nogen synlig aktivitet på databaserne, hvilket bringer spørgsmålene ind:Er standardværdierne forkerte? Hvis ja, hvad skal den rigtige størrelse være?

Hukommelsesstyring på SQL Server fungerer på Fill-and-Flush-algoritmen. Standardværdierne begrænser ikke hukommelsesforbruget i at vokse, medmindre der er en anmodning fra operativsystemet.

Dimensioneringen afhænger af forskellige komponenter i systemet - i mange tilfælde er det et godt udgangspunkt at sætte den mellem 70 % og 80 %. Derefter bør du også overvåge det for at se, hvad du ellers mangler, og om du skal justere indstillingen. Hvis du har andre tjenester på SQL Serveren (det burde du virkelig ikke), skal du muligvis efterlade flere, især hvis disse tjenester er hukommelsessvin. Overvej at gense hukommelsesindstillingen for SQL-forekomsten i et af følgende scenarier:

  • Operativsystemets manglende reaktion
  • Applicering
  • Sikkerhedskopiering, der kræver store hukommelsesbuffere
  • In-Memory-optimerede objekter
  • Kolonnelagerindekser, da de kræver store mængder hukommelse for at udføre indeksvedligeholdelse.

Hukommelsesindstillingen på SQL Server er ret ligetil. Du kan ændre værdien ved at bruge sp_configure eller SSMS GUI. Dette er en online mulighed, men husk, at indstilling eller nulstilling af disse værdier kan få nogle af de interne cache-objekter til at blande om, hvilket vil få systemet til at køre lidt langsommere.

sp_configure 'max server memory (MB)',

I dette tilfælde betyder tallet "2147483647", at SQL Server ikke har nogen øvre grænse og vil bruge al hukommelsen på serveren.

Min serverhukommelse:min serverhukommelse som bundværdi; SQL Server vil commit hukommelse til eget brug, indtil den når min server hukommelse indstilling. Derefter vil den bevare mindst denne mængde brugbar hukommelse.

Max serverhukommelse:På samme måde som min serverhukommelse giver et gulv, giver max serverhukommelse et loft.

Min. og maks. hukommelsesniveauer er den nedre og øvre grænse for mængden af ​​hukommelse, der er tilladt til brug af bufferpuljen. Bufferpuljen er den største del af hukommelsen, der forbruges af SQL Server. Følgende er SQL Server-komponenterne i SQL-instansen, der bruger hukommelse fra bufferpuljen

  • Databasesidecache
  • Interne logcacher
  • Cache for procedure eller forespørgselsplan
  • Forespørgselsarbejdsbelastningsrum
  • Låse (Hukommelsestilskud)
  • Forbindelseskontekst
  • Optimering af forespørgsler
  • Datastrukturer på systemniveau

Værdierne af de vigtige metrics såsom Available Mbytes, Pages/Sec, Buffer Cache Hit Ratio, PLE osv. bestemmer SQL Server-ydeevnen.

Buffer Cache Hit Ratio er specifik for hver applikation. 90% anses normalt for at være ønskeligt. Det betyder, at over 90 % af anmodningerne blev serveret af cachen, hvilket er en god ting. Hvis værdien er lavere, skal du tilføje mere hukommelse, indtil den konstant er højere end 90 %.

Tilgængelige bytes er intet andet end en indikation af, hvor meget hukommelse der er tilgængelig til brug. Tælleren Sider/sek. viser, hvor mange sider der blev hentet fra disken eller skrevet til disken, begge på grund af fejl på harddisken.

PLE står for Page Life Expectancy, som er en indikation af, hvor mange sekunder siden vil blive i poolen.

For eksempel,

$server = 'hqdbt01'

$counters = @("\Memory\Available MBytes",
 "\Memory\Pages/sec",
 "\SQLServer:Buffer Manager\Buffer cache hit ratio",
 "\SQLServer:Buffer Manager\Lazy writes/sec",
 "\SQLServer:Buffer Manager\Page life expectancy" 

 ) 
 $collections = Get-Counter -ComputerName $server -Counter $counters -SampleInterval 10 -MaxSamples 1
 Write-Output $collections 
 foreach ($collection in $collections) 
 {$sampling = $collection.CounterSamples | Select-Object -Property TimeStamp, Path, Cookedvalue 
  $sampling | Format-Table -AutoSize
   }

Anbefalinger og bedste praksis

Lad os nu kort se på teknikkerne til at dimensionere hukommelsen.

  1. 1 GB hukommelse reserveret til operativsystemet
  2. 1 GB hver for hver 4 GB RAM efter de første 4 GB, op til 16 GB RAM
  3. 1 GB hver for hver 8 GB i mere end 16 GB RAM

For eksempel, hvis du har en 32 GB RAM-databaseserver, vil hukommelse, der skal gives til operativsystemet være

  1. 1 GB, minimumstildelingen
  2. + 3 GB, da 16 GB – 4 GB =12 GB; 12 GB divideret med 4 GB (hver 4 GB får 1 GB) er 3 GB.
  3. + 2 GB, som 32 GB – 16 GB =16 GB; 16 divideret med 8 (hver 8 GB efter 16 GB får 1 GB) er 2 GB

Så i alt, for en server med 32 GB RAM, vil 7 GB blive reserveret til operativsystemet. Dette er den maksimale hukommelse, der er allokeret til SQL Server, der bør være 25 GB. Tilsvarende bør 10 GB reserveres til operativsystemet for en 64 GB-server, og 54 GB bør tildeles SQL Server.

Vi har alle på et eller andet tidspunkt hørt om eller brugt Windows Management Instrumentation (WMI). Der er flere klasser i WMI, som giver os mulighed for at udtrække information om hardwaren, installeret software, operativsystemet eller endda registreringsdatabasen. Vi kan endda ændre indstillinger og udføre handlinger på disse aspekter.

Win32_OperatingSystem-klassen er en WMI-klasse, der har alle de nødvendige oplysninger om den aktive operativsystem (i tilfælde af at du f.eks. er dobbelt opstart). Denne klasse kan også bruges til at få den mængde hukommelse, der er allokeret til operativsystemet. Her er nogle af de objekter, som klassen kan returnere, som kunne være til hjælp for os (hukommelsen måles i kilobytes af denne klasse):

  • TotalVisibleMemorySize :Dette felt viser den samlede fysiske hukommelse, der er tilgængelig for operativsystemet. Utilgængelige stykker hukommelse kan forårsage, at et mindre antal end installeret vises her.
  • FreePhysicalMemory :Dette fortæller os, hvor meget fysisk hukommelse der er ledig.
  • TotalVirtualMemorySize :Dette er den samlede virtuelle hukommelse, der er tilgængelig for OS at bruge. Dette omfatter den fysiske hukommelse, der er installeret på computeren, sammen med størrelsen på sidefilen.
  • FreeVirtualMemory :Svarer til FreePhysicalMemory, men inkluderer også den ledige plads i personsøgningshukommelsen.
$server='hqdbt01'
Get-WmiObject -Class Win32_OperatingSystem  -ComputerName $server | select  CSName,
@{name="TotalVirtualMemorySize";expression={($_.TotalVirtualMemorySize/1024).tostring("N0")}},
@{name="TotalVisibleMemorySize";expression={($_.TotalVisibleMemorySize/1024).tostring("N0")}},
@{name="FreePhysicalMemory";expression={($_.FreePhysicalMemory/1024).tostring("N0")}},
@{name="FreeVirtualMemory";expression={($_.FreeVirtualMemory/1024).tostring("N0")}},
@{name="FreeSpaceInPagingFiles";expression={($_.FreeSpaceInPagingFiles/1024).tostring("N0")}},
NumberofProcesses,
NumberOfUsers 

Vi kan hente sidefiloplysningerne ved hjælp af Win32_PageFileSetting WMI-klassen.

$server='hqdbt01'
Get-WMIObject Win32_PageFileSetting -Computer $server|  select @{name="ServerName";expression={$_.__Server}}, Name, InitialSize, MaximumSize 

Følgende forespørgsel giver detaljerne om hukommelsesbrug på højt niveau for SQL-forekomsten.

SELECT 
	physical_memory_in_use_kb/1024 Physical_memory_in_use_MB, 
    large_page_allocations_kb/1024 Large_page_allocations_MB, 
    locked_page_allocations_kb/1024 Locked_page_allocations_MB,
    virtual_address_space_reserved_kb/1024 VAS_reserved_MB, 
    virtual_address_space_committed_kb/1024 VAS_committed_MB, 
    virtual_address_space_available_kb/1024 VAS_available_MB,
    page_fault_count Page_fault_count,
    memory_utilization_percentage Memory_utilization_percentage, 
    process_physical_memory_low Process_physical_memory_low, 
    process_virtual_memory_low Process_virtual_memory_low
FROM sys.dm_os_process_memory;

Forbered scriptet

Lad os integrere de førnævnte tre udgange i en enkelt hukommelsesudgang:

  1. SQL interne hukommelsesstrukturer ved hjælp af tæller
  2. Tilgængelig virtuel og fysisk hukommelse ved hjælp af WMI-objekt
  3. Sidefilindstilling ved hjælp af WMI

HTML-indholdsforberedelsen handler om at udfylde værdien fra den forskellige sektion af scriptet mellem de rigtige tags.

Scriptet kan bygge gyldige HTML-tags. Følgende er de funktioner, der bruges i scriptet.

  1. writeHTMLHeader:Denne funktion bruges til at generere headeren og definere typografien for HTML-filen.
  2. writetableFooter:dette definerer de afsluttende HTML-tags.
  3. writeTableHeader:dette definerer den tretten-spaltede outputoverskrift for HTML-filen
  4. writeMemoryInfo:dette er den funktion, der udfører sammenlægningen af ​​de to WMI-klasseoutput. Outputtet af Win32_PageFileSetting, Win32_OperatingSystem og SMO SQL sendes som argumenter for denne funktion. Værdierne kan også transformeres eller manipuleres yderligere i dette afsnit.
  5. E-mailsektion

[expand title="Kode"]

# First, let’s create a text file, where we will later save memory details


$MailServer='mail01.example.com'

$MemoryFileName = "f:\PowerSQL\Memory.htm"
New-Item -ItemType file $MemoryFileName -Force
# Function to write the HTML Header to the file
Function writeHtmlHeader
{
param($fileName)
$date = ( get-date ).ToString('yyyy/MM/dd')
Add-Content $fileName "<html>"
Add-Content $fileName "<head>"
Add-Content $fileName "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"
Add-Content $fileName '<title>SQLShack Memory Usage Report </title>'
add-content $fileName '<STYLE TYPE="text/css">'
add-content $fileName  "<!--"
add-content $fileName  "td {"
add-content $fileName  "font-family: Tahoma;"
add-content $fileName  "font-size: 11px;"
add-content $fileName  "border-top: 1px solid #999999;"
add-content $fileName  "border-right: 1px solid #999999;"
add-content $fileName  "border-bottom: 1px solid #999999;"
add-content $fileName  "border-left: 1px solid #999999;"
add-content $fileName  "padding-top: 0px;"
add-content $fileName  "padding-right: 0px;"
add-content $fileName  "padding-bottom: 0px;"
add-content $fileName  "padding-left: 0px;"
add-content $fileName  "}"
add-content $fileName  "body {"
add-content $fileName  "margin-left: 5px;"
add-content $fileName  "margin-top: 5px;"
add-content $fileName  "margin-right: 0px;"
add-content $fileName  "margin-bottom: 10px;"
add-content $fileName  ""
add-content $fileName  "table {"
add-content $fileName  "border: thin solid #000000;"
add-content $fileName  "}"
add-content $fileName  "-->"
add-content $fileName  "</style>"
Add-Content $fileName "</head>"
Add-Content $fileName "<body>"

add-content $fileName  "<table width='100%'>"
add-content $fileName  "<tr bgcolor='#CCCCCC'>"
add-content $fileName  "<td colspan='13' height='25' align='center'>"
add-content $fileName  "<font face='tahoma' color='#003399' size='4'><strong>SQLShack Memory Usage Report - $date</strong></font>"
add-content $fileName  "</td>"
add-content $fileName  "</tr>"
add-content $fileName  "</table>"

}

# Function to write the HTML Header to the file
Function writeTableHeader
{
param($fileName)

Add-Content $fileName "<tr bgcolor=#CCCCCC>"
Add-Content $fileName "<td width='10%' align='center'>ServerName</td>"
Add-Content $fileName "<td width='10%' align='center'>TotalVirtualMemorySize</td>"
Add-Content $fileName "<td width='10%' align='center'>TotalVisibleMemorySize</td>"
Add-Content $fileName "<td width='10%' align='center'>FreePhysicalMemory</td>"
Add-Content $fileName "<td width='10%' align='center'>FreeVirtualMemory</td>"
Add-Content $fileName "<td width='10%' align='center'>FreeSpaceInPagingFiles</td>"
Add-Content $fileName "<td width='10%' align='center'>NumberofProcesses</td>"
Add-Content $fileName "<td width='10%' align='center'>NumberOfUsers</td>"
Add-Content $fileName "<td width='10%' align='center'>PageFile</td>"
Add-Content $fileName "<td width='10%' align='center'>Page-InitialSize</td>"
Add-Content $fileName "<td width='10%' align='center'>Page-MaxSize</td>"
Add-Content $fileName "<td width='10%' align='center'>SQLMaxMemory</td>"
Add-Content $fileName "<td width='10%' align='center'>SQLMinMemory</td>"
Add-Content $fileName "<td width='10%' align='center'>Memory Available MBytes</td>"
Add-Content $fileName "<td width='10%' align='center'>Buffer Cache Hit Ratio</td>"
Add-Content $fileName "<td width='10%' align='center'>PLE</td>"
Add-Content $fileName "</tr>"
}

Function writeHtmlFooter
{
param($fileName)

Add-Content $fileName "</body>"
Add-Content $fileName "</html>"
}

Function writeMemoryInfo
{
param($filename,$csname,$TotalVirtualMemorySize,$TotalVisibleMemorySize,$FreePhysicalMemory,$FreeVirtualMemory,$FreeSpaceInPagingFiles,$NumberofProcesses,$NumberOfUsers,$PageFile,$initialSize,$MaxSize,$SQLMaxMemory, $SQLMinMemory ,$mAvailableMBytes, $Buffercachehitratio, $PLE )
 Add-Content $fileName "<tr>"
 Add-Content $fileName "<td>$csname </td>"
 Add-Content $fileName "<td>$TotalVirtualMemorySize </td>"
 Add-Content $fileName "<td>$TotalVisibleMemorySize</td>"
 Add-Content $fileName "<td>$FreePhysicalMemory </td>"
 Add-Content $fileName "<td>$FreeVirtualMemory </td>"
 Add-Content $fileName "<td>$FreeSpaceInPagingFiles </td>"
 Add-Content $fileName "<td>$NumberofProcesses </td>"
 Add-Content $fileName "<td>$NumberOfUsers</td>"
 Add-Content $fileName "<td>$PageFile</td>"
 Add-Content $fileName "<td>$initialSize</td>"
 Add-Content $fileName "<td>$MaxSize</td>"
 Add-Content $fileName "<td>$SQLMaxMemory</td>"
 Add-Content $fileName "<td>$SQLMinMemory</td>"
 Add-Content $fileName "<td>$mAvailableMBytes</td>"
 Add-Content $fileName "<td>$Buffercachehitratio</td>"
 Add-Content $fileName "<td>$PLE</td>"
 
 Add-Content $fileName "</tr>"
}

Function sendEmail  

 { 
param($from,$to,$subject,$smtphost,$htmlFileName)  

$body = Get-Content $htmlFileName 
$body = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body 
$body.isBodyhtml = $true
$smtpServer = $MailServer
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($body)

    

 }  


writeHtmlHeader $MemoryFileName
 Add-Content $MemoryFileName "<table width='100%'><tbody>"
 Add-Content $MemoryFileName "<tr bgcolor='#CCCCCC'>"
 Add-Content $MemoryFileName "<td width='100%' align='center' colSpan=16><font face='tahoma' color='#003399' size='2'><strong> Memory Usage Details</strong></font></td>"
 Add-Content $MemoryFileName "</tr>"

 writeTableHeader $MemoryFileName

foreach ($svr in get-content "\\hqdbsp18\f$\PowerSQL\Server.txt"){

$page=Get-WMIObject Win32_PageFileSetting -Computer $svr|  select __Server, Name, InitialSize, MaximumSize
$dp = Get-WmiObject -Class Win32_OperatingSystem  -ComputerName $svr | select  CSName,
@{name="TotalVirtualMemorySize";expression={($_.TotalVirtualMemorySize/1024).tostring("N0")}},
@{name="TotalVisibleMemorySize";expression={($_.TotalVisibleMemorySize/1024).tostring("N0")}},
@{name="FreePhysicalMemory";expression={($_.FreePhysicalMemory/1024).tostring("N0")}},
@{name="FreeVirtualMemory";expression={($_.FreeVirtualMemory/1024).tostring("N0")}},
@{name="FreeSpaceInPagingFiles";expression={($_.FreeSpaceInPagingFiles/1024).tostring("N0")}},
NumberofProcesses,
NumberOfUsers

$srv = new-object ('Microsoft.SqlServer.Management.Smo.Server') ($svr)
write-host $srv.Configuration.MaxServerMemory.RunValue 
write-host $srv.Configuration.MinServerMemory.RunValue 


$counters = @("\Memory\Available MBytes",
 "\Memory\Pages/sec",
 "\SQLServer:Buffer Manager\Buffer cache hit ratio",
 "\SQLServer:Buffer Manager\Lazy writes/sec",
 "\SQLServer:Buffer Manager\Page life expectancy"
  ) 
 $collections = Get-Counter -ComputerName $svr -Counter $counters -SampleInterval 5 -MaxSamples 1
 Write-Output $collections 
 foreach ($collection in $collections) 
    {
     $sampling = $collection.CounterSamples | Select-Object -Property TimeStamp, Path, Cookedvalue 
     foreach($sam in $sampling)
        {
            if ($sam.Path -like "*\Memory\Available MBytes*") {
                $mAvailableMBytes=$sam.CookedValue
                }
            elseif ($sam.Path -like "*Buffer Manager\Buffer cache hit ratio*") {
                $Buffercachehitratio=$sam.CookedValue
            }
            elseif ($sam.Path -like "*Page life expectancy*") {
                $PLE=$sam.CookedValue}
        }
    }
write-host $mAvailableMBytes $Buffercachehitratio $PLE


Write-Host  $dp.csname $dp.TotalVirtualMemorySize $dp.TotalVisibleMemorySize $dp.FreePhysicalMemory $dp.FreeVirtualMemory $dp.FreeSpaceInPagingFiles $dp.NumberofProcesses $dp.NumberOfUsers  $page.InitialSize $page.Name $page.MaximumSize $srv.Configuration.MaxServerMemory.RunValue $srv.Configuration.MinServerMemory.RunValue  $mAvailableMBytes $Buffercachehitratio $PLE
writeMemoryInfo $MemoryFileName $dp.csname $dp.TotalVirtualMemorySize $dp.TotalVisibleMemorySize $dp.FreePhysicalMemory $dp.FreeVirtualMemory $dp.FreeSpaceInPagingFiles $dp.NumberofProcesses $dp.NumberOfUsers  $page.Name $page.InitialSize $page.MaximumSize $srv.Configuration.MaxServerMemory.RunValue $srv.Configuration.MinServerMemory.RunValue $mAvailableMBytes $Buffercachehitratio $PLE

 }


  Add-Content $MemoryFileName "</table>" 

writeHtmlFooter $MemoryFileName 
$date = ( get-date ).ToString('yyyy/MM/dd')
sendEmail [email protected] [email protected] "Memory Usage Report - $Date" $MailServer $MemoryFileName
 

[/udvid]

Output

Afslutning

Nu hvor du har lært nogle nye ting om SQL Server-hukommelseshåndtering, vil du bedre forstå SQL Server-ressourcer.

Hvis der er tilstrækkelig RAM på serveren, kan datasiderne få en længere levetid i bufferpuljen, hvilket resulterer i en drastisk reduktion af I/O-behovet.

Mens databaseadministratorer i de fleste tilfælde er afhængige af standardhukommelsesindstillinger, er vi nødt til at forstå, at kravene til intern hukommelse afhænger af instansens arbejdsbyrde.

Denne artikel er en gennemgang på højt niveau af SQL Server-hukommelse og dens interne funktioner. Den dækker også de forskellige årsager bag ydeevneflaskehalse forårsaget af ikke at indstille den maksimale hukommelse.

Jeg har inkluderet trinvise instruktioner til at opsætte og konfigurere en hukommelsesrapport. Trinene til, hvordan du indstiller SQL-hukommelsen, er også inkluderet. Yderligere diskuterede vi forskellige SQL-komponenter, der bidrager til brugen af ​​den tilgængelige hukommelse i SQL Server-miljøet.

Et punkt at huske er, at allokering og de-allokering af hukommelse forsinker opstarten. Derfor, hvis du har flere programmer, der stopper og starter på den samme server, kan det påvirke ydeevnen. På samme måde, hvis der er flere andre applikationer, der kører på den samme server, bliver indstilling af min serverhukommelse og max serverhukommelse vigtigere for at sikre optimal ydeevne.

Det var alt for nu...

Referencer

  1. Overvågning af hukommelsesforbrug
  2. Vigtigheden af ​​at indstille Max Server Memory i SQL Server og hvordan man indstiller den
  3. Konfigurationsindstillinger for serverhukommelsesserver

  1. SIGN() Eksempler i SQL Server

  2. SQL Ydeevne UNION vs. OR

  3. SQL Server, hvordan indstilles automatisk stigning efter oprettelse af en tabel uden tab af data?

  4. SQL Server Full Text Search Escape Characters?