Le choix des disques durs est crucial pour obtenir de bonnes performances avec SQL Server, toutes versions confondues : des disques SAS 15000 rpm seront bien sûr plus performants que des SATA II 7200 rpm. Les premiers offriront un nombre d’entrées sorties par seconde plus élevé et donc des taux de transferts plus importants, ce qui est extrêmement important dans le cas d’une utilisation dans un serveur de bases de données où le facteur limitant est souvent la performance du RAID et non la puissance du processeur.
Il existe un moyen relativement peu connu permettant d’augmenter encore le nombre d’entrées/sorties par seconde (IOs/s) sous Windows 2003 si vous utilisez un RAID : l’alignement de partitions. Depuis Windows 2008 la création de partition gère automatiquement cette optimisation mais sous Windows 2003 il faut le faire manuellement.
Un peu de théorie
Il faut tout d’abord comprendre comment un RAID et une partition sont organisés sur les disques. Un RAID est organisé en stripes de taille déterminée lors de la création du RAID (64 ko, 128 ko, 256 ko sont des tailles fréquentes et recommandées pour SQL Server). Dans le cas de stripes de 64 ko, on compte 128 secteurs par stripe. Lorsqu’une partition est créée sur le RAID, il convient d’utiliser la même taille pour les clusters (ou unités d’allocation), c’est-à-dire dans notre cas 64 ko. Dans le meilleur des mondes un cluster de 64 ko utiliserait un stripe de 64 ko. Le problème est que les 63 premiers secteurs du premier stripe sont cachés et utilisés entre autre par le Master Boot Record. Conséquence, le premier cluster de données de la partition utilisateur se retrouve à cheval sur la fin du premier stripe et sur le début du second. Cela signifie que pour lire le contenu du premier cluster (et d’ailleurs de tous les autres clusters) il faudra en réalité lire deux stripes, ce qui implique une baisse de performances évidente bien que difficilement chiffrable a priori.
Le principe de l’alignement de partition est de décaler le premier cluster de données utilisateur au début du deuxième stripe (ou même plus du moment que le début et la fin du cluster coïncident avec le début et la fin d’un stripe). Du coup la lecture (ou l’écriture) d’un cluster correspondra à la lecture (ou à l’écriture) d’un stripe. Nous devrions alors observer une amélioration des performances du disque. A partir de Windows 2008 la cration d’une partition se fait automatiquement avec un décalage de 1 Mo, une valeur qui permet de s’affranchir de la plupart des cas de figure (stripes de tailles différentes, SANs, etc).
Un peu de pratique
Passons à présent à la pratique. Sur un serveur Windows 2003 en RAID, ouvrez une fenêtre DOS et entrez la commande suivante :
wmic partition get BlockSize, StartingOffset, Name, Index
Sur mon serveur voilà ce que j’ai obtenu :
BlockSize Index Name StartingOffset
512 0 Disque n° 0, partition n° 0 32256
512 0 Disque n° 1, partition n° 0 32256
512 0 Disque n° 2, partition n° 0 32256
512 0 Disque n° 3, partition n° 0 32256
Le disque n°1 correspond au disque stockant la base TempDB, le n°2 au disque stockant les logs et le n°3 au disque stockant les bases en RAID 5. Le numéro des disques est le même que celui disponible dans le Panneau de configuration > Outils d’administration > Gestion de l’ordinateur > Gestion des disques.
La colonne qui va nous intéresser ici est la colonne Starting Offset qui nous indique à quel octet commence la partition. Pour le disque 3, on constate que cet offset vaut 32256 octets, ce qui correspond bien aux 63 secteurs cachés de 512 octets dont nous avons parlé plus haut. La partition ne commence donc pas au début d’un cluster : elle est mal alignée.
Pour aligner correctement cette partition il va nous falloir la recréer, ce qui veut dire qu’il faut supprimer la partition actuelle. Si vous avez des données sur cette partition cela pose problème bien sûr, et il vous faudra les sauvegarder quelque part… Vous pouvez utiliser la commande suivante pour copier ailleurs ces données tout en conservant les droits NTFS :
xcopy e:\dossier c:\dossier /O /X /E /H /K
Une fois que vous êtes certains d’avoir bien sauvegardé vos données, rendez-vous dans le Panneau de configuration > Outils d’administration > Gestion de l’ordinateur > Gestion des disques et supprimez la partition en faisant un clic droit dessus et en sélectionnant Supprimer la partition… Faites bien attention à ce que vous supprimez !
Ouvrez ensuite une fenêtre DOS et entrez les commandes suivantes :
diskpart list disk
Sur mon serveur j’obtiens le résultat suivant :
Le disque 3 est bien disponible, nous pouvons créer une partition avec un décalage de 1024 ko (comme sous Windows 2008) :
select disk 3 create partition primary align=1024
Après quelques secondes le message suivant s’affiche :
DiskPart a réussi à créer la partition spécifiée.
Tapez ensuite exit pour quitter DiskPart et tapez la commande suivante :
wmic partition get BlockSize, StartingOffset, Name, Index
Cette fois on obtient :
BlockSize Index Name StartingOffset
512 0 Disque n° 0, partition n° 0 32256
512 0 Disque n° 1, partition n° 0 32256
512 0 Disque n° 2, partition n° 0 32256
512 0 Disque n°3, partition n° 0 1048576
1048576 correspond pile à 1 Mo (1024 x 1024), ou encore à 16 stripes de 64 ko (16 x 64 x 1024). La partition est donc bien alignée.
Il ne reste plus qu’à mettre la partition en production, pour cela retournez dans la Gestion des Disques, faites un clic droit sur la partition, puis Marquer la partition comme active. Faites ensuite un nouveau clic droit sur la partition puis sélectionnez Modifier la lettre de lecteur et les chemins d’accès… et sélectionnez la lettre de votre choix (si vous aviez des données sur l’ancienne partition c’est une bonne idée de remettre la même lettre). Enfin, faites un clic droit sur la partition et sélectionnez Formater. Choisissez un nom de partition (si vous aviez des données sur l’ancienne partition c’est (encore) une bonne idée de remettre le même nom), une taille d’unité d’allocation de 64 K et cochez la case Effectuer un formatage rapide.
Test de performances
Voyons à présent comment faire quelques tests de performances ciblés pour SQL Server. Commencez par télécharger SQLIO et installez-le.
Rendez-vous ensuite dans C:\Program Files\SQLIO (ou C:\Program Files (x86)\SQLIO sur un serveur 64 bits) et éditez le fichier param.txt pour n’avoir qu’une seule ligne (modifiez la lettre de votre partition) :
E:\test.dat 2 0x0 102400
Cela servira à créer un fichier E:\test.dat simulant une base SQL de 100 Go sur lequel nous pourrons effectuer des test de lecture/écriture. Pour créer ce fichier, ouvrez une console DOS et entrez la commande suivante :
sqlio -kW -s5 -fsequential -o4 -b64 -Fparam.txt
Sur mon système en RAID 5 sur 6 disques SCSI 320 15000 rpm cette commande a pris 18 minutes pour créer le fichier de test de 100 Go.
Toujours dans le répertoire de SQLIO, créez quatre fichiers contenant les lignes suivantes :
1) lectures_aleatoire.cmd : ce fichier simulera des recherches de valeurs indexées ou la lecture de bases fragmentées.
sqlio -dE -BH -kR -frandom -t1 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t2 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t4 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t8 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t8 -o2 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t8 -o4 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t8 -o8 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t8 -o16 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t8 -o32 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t8 -o64 -s90 -b64 test.dat
sqlio -dE -BH -kR -frandom -t8 -o128 -s90 -b64 test.dat
2) lectures_sequentiel.cmd : ce fichier simulera des lectures d’index ou de tables non fragmentées.
sqlio -dE -BH -kR -fsequential -t1 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t2 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t4 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t8 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t8 -o2 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t8 -o4 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t8 -o8 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t8 -o16 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t8 -o32 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t8 -o64 -s90 -b64 test.dat
sqlio -dE -BH -kR -fsequential -t8 -o128 -s90 -b64 test.dat
3) ecritures_aleatoire.cmd : ce fichier simulera des écritures de données dans des bases fragmentées ou de taille conséquente.
sqlio -dE -BH -kW -frandom -t1 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t2 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t4 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t8 -o1 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t8 -o2 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t8 -o4 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t8 -o8 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t8 -o16 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t8 -o32 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t8 -o64 -s90 -b64 test.dat
sqlio -dE -BH -kW -frandom -t8 -o128 -s90 -b64 test.dat
4) ecritures_sequentiel.cmd : ce fichier simulera l’écriture dans les fichiers de logs.
sqlio -dE -BH -kW -fsequential -t1 -o1 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t2 -o1 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t4 -o1 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t8 -o1 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t8 -o2 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t8 -o4 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t8 -o8 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t8 -o16 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t8 -o32 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t8 -o64 -s90 -b8 test.dat
sqlio -dE -BH -kW -fsequential -t8 -o128 -s90 -b8 test.dat
Ces quatre fichiers lanceront des test en simulant 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 ou 1024 threads.
Il ne reste plus qu’à lancer ces tests dans une fenêtre DOS en tapant ces commandes les unes après les autres (chaque test prend environ 15-20 minutes) :
lectures_aleatoire.cmd > c:\Program Files\SQLIO\lectures_aleatoires.txt lectures_sequentiel.cmd > c:\Program Files\SQLIO\lectures_sequentiel.txt ecritures_aleatoire.cmd > c:\Program Files\SQLIO\ecritures_aleatoire.txt ecritures_sequentiel.cmd > c:\Program Files\SQLIO\ecritures_sequentiel.txt
Dans les fichiers txt stockant les résultats vous pourrez noter les valeurs IOs/s et MBs/s pour chaque valeur de threads.
Dans les graphiques suivants j’ai noté les valeurs obtenues sur mon système avant et après alignement.
Comme vous pouvez le constater l’amélioration des performances est évidente et ce dans tous les cas de figure. L’alignement de partition est donc un point fondamental à mettre en place lors de l’installation d’un serveur SQL.