Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comprendre l'importance du paramètre de mémoire dans SQL Server

La mémoire est l'une des ressources formant le triangle des performances, le processeur et le stockage étant les deux autres. Si l'un est touché, les deux autres prennent la charge pour essayer d'amener les performances à des niveaux acceptables, mais il y a toujours le compromis. Quelles que soient les transactions qui ne peuvent pas être validées dans la mémoire, elles seront transmises au sous-système de disque par SQL Server. Cela provoque un goulot d'étranglement des performances. Par conséquent, les statistiques d'attente peuvent aider à identifier les problèmes de performances sur un serveur SQL.

Dans cet article, les sujets suivants sont abordés :

  1. Comprendre les éléments internes des paramètres et de la configuration de la mémoire SQL Server
  2. La mémoire SQL Server et son impact sur les performances de la base de données et des applications
  3. Discuter des différents composants SQL Server qui contribuent à l'utilisation de la mémoire
  4. Bonnes pratiques et recommandations pour le dimensionnement de la mémoire
  5. Rapport sur la mémoire multi-serveurs
  6. Et plus…

Internes de gestion de la mémoire

SQL Server dispose d'une unité de gestion de la mémoire qui effectue une gestion dynamique de la mémoire automatisée en fonction de la charge de travail du système. Cette mémoire est l'espace volatil essentiel aux besoins Business - Tech d'aujourd'hui, dont le bon dimensionnement est vital pour la performance optimale des applications.

Cependant, nous savons tous que lors de la configuration du serveur, le dimensionnement contient certaines valeurs par défaut. dans certains cas, nous découvrons rapidement que SQL Server utilise la quasi-totalité de la mémoire du serveur, même s'il n'y a aucune activité visible sur les bases de données, ce qui soulève les questions :les valeurs par défaut sont-elles incorrectes ? Si oui, quelle devrait être la bonne taille ?

La gestion de la mémoire sur SQL Server fonctionne sur l'algorithme Fill-and-Flush. Les valeurs par défaut n'empêchent pas la consommation de mémoire d'augmenter à moins qu'il y ait une demande du système d'exploitation.

Le dimensionnement dépend de divers composants du système. Dans de nombreux cas, le fixer entre 70 % et 80 % est un bon point de départ. Ensuite, vous devez également le surveiller pour voir ce qui vous manque et si vous devez modifier le paramètre. Si vous avez d'autres services sur SQL Server (vous ne devriez vraiment pas), vous devrez peut-être en laisser plus, surtout si ces services sont gourmands en mémoire. Envisagez de revoir le paramètre de mémoire de l'instance SQL dans l'un des scénarios suivants :

  • Non-réponse du système d'exploitation
  • Épuisement des candidatures
  • Opérations de sauvegarde nécessitant de grandes mémoires tampons
  • Objets optimisés en mémoire
  • Les index de stockage en colonnes, car ils nécessitent de grands volumes de mémoire pour effectuer les maintenances d'index.

Le paramètre de mémoire sur SQL Server est assez simple. Vous pouvez modifier la valeur à l'aide de sp_configure ou l'interface graphique SSMS. Il s'agit d'une option en ligne, mais n'oubliez pas que la définition ou la réinitialisation de ces valeurs peut entraîner le remaniement de certains objets du cache interne, ce qui ralentira légèrement le fonctionnement du système.

sp_configure 'max server memory (MB)',

Dans ce cas, le nombre "2147483647" signifie que SQL Server n'a pas de limite supérieure et utilisera toute la mémoire du serveur.

Mémoire serveur minimale :mémoire serveur minimale comme valeur plancher ; SQL Server validera la mémoire pour son propre usage jusqu'à ce qu'il atteigne le paramètre de mémoire minimale du serveur. Après cela, il conservera au moins cette quantité de mémoire utilisable.

Mémoire maximale du serveur :de la même manière que la mémoire minimale du serveur fournit un plancher, la mémoire maximale du serveur fournit un plafond.

Les niveaux de mémoire minimum et maximum sont les limites inférieure et supérieure de la quantité de mémoire autorisée pour l'utilisation par le pool de mémoire tampon. Le pool de mémoire tampon est le plus grand bloc de mémoire consommé par SQL Server. Voici les composants SQL Server de l'instance SQL qui utilisent la mémoire du pool de mémoire tampon

  • Cache de pages de base de données
  • Caches de journaux internes
  • Cache de procédure ou cache de plan de requête
  • Interroger l'espace de charge de travail
  • Verrous (octrois de mémoire)
  • Contexte de connexion
  • Optimisation des requêtes
  • Structures de données au niveau du système

Les valeurs des métriques importantes telles que les Mo disponibles, les Pages/Sec, le Buffer Cache Hit Ratio, PLE, etc. déterminent les performances de SQL Server.

Le Buffer Cache Hit Ratio est spécifique à chaque application. 90% est généralement considéré comme souhaitable. Cela signifie que plus de 90% des requêtes ont été servies par le cache, ce qui est une bonne chose. Si la valeur est inférieure, ajoutez plus de mémoire jusqu'à ce qu'elle soit constamment supérieure à 90 %.

Les octets disponibles ne sont rien d'autre qu'une indication de la quantité de mémoire disponible pour l'utilisation. Le compteur Pages/sec indique le nombre de pages extraites du disque ou écrites sur le disque, toutes deux dues à des erreurs matérielles de page.

PLE signifie Page Life Expectancy, qui indique combien de secondes la page restera dans le pool.

Par exemple,

$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
   }

Recommandations et bonnes pratiques

Voyons maintenant brièvement les techniques pour dimensionner la mémoire.

  1. 1 Go de mémoire réservée au système d'exploitation
  2. 1 Go chacun pour 4 Go de RAM après les 4 Go initiaux, jusqu'à 16 Go de RAM
  3. 1 Go chacun pour 8 Go dans plus de 16 Go de RAM

Par exemple, si vous avez un serveur de base de données de 32 Go de RAM, la mémoire à attribuer au système d'exploitation serait

  1. 1 Go, l'allocation minimale
  2. + 3 Go, puisque 16 Go – 4 Go =12 Go ; 12 Go divisés par 4 Go (chaque 4 Go reçoit 1 Go) donnent 3 Go.
  3. + 2 Go, car 32 Go - 16 Go =16 Go ; 16 divisé par 8 (chaque 8 Go après 16 Go donne 1 Go) correspond à 2 Go

Ainsi, au total, pour un serveur doté de 32 Go de RAM, 7 Go seront réservés au système d'exploitation. Il s'agit de la mémoire maximale allouée à SQL Server qui doit être de 25 Go. De même, pour un serveur de 64 Go, 10 Go doivent être réservés au système d'exploitation et 54 Go doivent être alloués à SQL Server.

Nous avons tous, à un moment ou à un autre, entendu parler ou utilisé Windows Management Instrumentation (WMI). Il existe plusieurs classes dans WMI, qui nous permettent d'extraire des informations sur le matériel, les logiciels installés, le système d'exploitation ou même le registre. Nous pouvons même modifier les paramètres et effectuer des actions sur ces aspects.

La classe win32_OperatingSystem est une classe WMI qui contient toutes les informations nécessaires sur le actif système d'exploitation (dans le cas où vous êtes, par exemple, à double démarrage). Cette classe peut également être utilisée pour obtenir la quantité de mémoire allouée au système d'exploitation. Voici quelques-uns des objets que la classe peut renvoyer, qui pourraient nous être utiles (la mémoire est mesurée en kilo-octets par cette classe) :

  • Taille totale de la mémoire visible :Ce champ affiche la mémoire physique totale accessible au système d'exploitation. Des blocs de mémoire inaccessibles peuvent entraîner l'affichage ici d'un nombre inférieur à celui installé.
  • Mémoire physique gratuite  :Cela nous indique quelle quantité de mémoire physique est libre.
  • Taille totale de la mémoire virtuelle :Il s'agit de la mémoire virtuelle totale disponible pour le système d'exploitation à utiliser. Cela comprend la mémoire physique installée sur l'ordinateur, ainsi que la taille du fichier d'échange.
  • Mémoire virtuelle gratuite  :Similaire à FreePhysicalMemory, mais inclut également l'espace libre dans la mémoire de pagination.
$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 

Nous pouvons récupérer les informations du fichier de page à l'aide de la classe WMI Win32_PageFileSetting.

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

La requête suivante donne les détails d'utilisation de la mémoire de haut niveau de l'instance SQL.

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;

Préparer le scénario

Intégrons les trois sorties susmentionnées dans une seule sortie mémoire :

  1. Structures de mémoire interne SQL utilisant Counter
  2. Mémoire virtuelle et physique disponible à l'aide d'un objet WMI
  3. Configuration du fichier d'échange à l'aide de WMI

La préparation du contenu HTML consiste à renseigner la valeur issue des différentes sections du script, entre les bonnes balises.

Le script peut créer des balises HTML valides. Voici les fonctions utilisées dans le script.

  1. writeHTMLHeader :cette fonction permet de générer le Header et de définir le style du fichier HTML.
  2. writetableFooter :définit les balises HTML de fermeture.
  3. writeTableHeader :définit l'en-tête de sortie à treize colonnes pour le fichier HTML
  4. writeMemoryInfo :c'est la fonction qui effectue la fusion des deux sorties de la classe WMI. La sortie de Win32_PageFileSetting, Win32_OperatingSystem et SMO SQL est transmise en tant qu'arguments pour cette fonction. Les valeurs peuvent également être davantage transformées ou manipulées dans cette section.
  5. Section e-mail

[expand title=”Code”]

# 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
 

[/expand]

Sortie

Conclusion

Maintenant que vous avez appris de nouvelles choses sur la gestion de la mémoire SQL Server, vous comprendrez mieux les ressources SQL Server.

S'il y a suffisamment de RAM sur le serveur, les pages de données peuvent avoir une durée de vie plus longue dans le pool de mémoire tampon, ce qui entraîne par conséquent une réduction drastique des besoins d'E/S.

Alors que dans la plupart des cas, les administrateurs de base de données s'appuient sur les paramètres de mémoire par défaut, nous devons comprendre que les besoins internes en mémoire dépendent de la charge de travail de l'instance.

Cet article est une présentation de haut niveau de la mémoire SQL Server et de ses éléments internes. En outre, il couvre les différentes raisons des goulots d'étranglement des performances causés par la non-définition de la mémoire maximale.

J'ai inclus des instructions étape par étape pour configurer et configurer un rapport de mémoire. Les étapes de configuration de la mémoire SQL sont également incluses. En outre, nous avons discuté de divers composants SQL qui contribuent à l'utilisation de la mémoire disponible sur l'environnement SQL Server.

Un point à retenir est que l'allocation et la désallocation de mémoire ralentissent le démarrage. Par conséquent, si plusieurs applications s'arrêtent et démarrent sur le même serveur, cela peut affecter les performances. De même, si plusieurs autres applications s'exécutent sur le même serveur, la définition de la mémoire minimale du serveur et de la mémoire maximale du serveur devient plus importante pour garantir des performances optimales.

C'est tout pour le moment…

Références

  1. Surveillance de l'utilisation de la mémoire
  2. Importance de définir la mémoire maximale du serveur dans SQL Server et comment la définir
  3. Options de configuration du serveur de mémoire du serveur