Instant File Initialization est une option connue des DBA et permet d’accélérer certaines opérations faisant de la réservation d’espace disque. Avec SQL Server cela se traduit par les opérations de création, restauration de bases de données ou encore ajout de fichiers, modification de taille ou encore expansion de fichiers … Bref cette option est souvent très bénéfique pour les performances mais celle-ci exige quelques prérequis qui sont les suivants :
- Le fichier n’est pas un fichier journal d’une base de données
- Le système d’exploitation supporte l’utilisation de la fonction SetFileValidData()
- Le compte de service SQL possède le privilège SE_MANAGE_VOLUME_NAME
- Le fichier n’est pas un fichier sparse
- Le fichier n’est pas concernée par du chiffrement TDE
- Trace flag 1806 n’est pas activé sur l’instance SQL (ce traceflag désactive l’utilisation de cette fonctionnalité)
Ce qui nous intéresse ici c’est l’utilisation de la fonction SetFileValidData(). Nous voila donc plongé dans la documentation des API Windows et de notre fonction SetFileValidData(). Voici ce que la documentation nous propose :
Sets the valid data length of the specified file. This function is useful in very limited scenarios. For more information, see the Remarks section.
Dans la section remarques nous avons :
The SetFileValidData function sets the logical end of a file. To set the size of a file, use the SetEndOfFile function. The physical file size is also referred to as the end of the file.
Each file stream has the following properties:
- File size: the size of the data in a file, to the byte.
- Allocation size: the size of the space that is allocated for a file on a disk, which is always an even multiple of the cluster size.
- Valid data length: the length of the data in a file that is actually written, to the byte. This value is always less than or equal to the file size.
…
The SetFileValidData function allows you to avoid filling data with zeros when writing nonsequentially to a file. The function makes the data in the file valid without writing to the file. As a result, although some performance gain may be realized, existing data on disk from previously existing files can inadvertently become available to unintended readers
…
A caller must have the SE_MANAGE_VOLUME_NAME privilege enabled when opening a file initially
Pour résumer : cette fonction va nous permettre d’éviter le remplissage de zéros dans un fichier lorsque les écritures ne sont pas séquentielles
Pourquoi pour des opérations non séquentielles ? Effectivement si l’on écrit de manière séquentielle dans un fichier la phase d’écriture de zéro est relativement rapide puisque l’on écrit toujours à la suite des données précédentes
Cependant si l’on écrit de manière aléatoire, le problème est tout autre. Imaginez que l’on écrive la première au début du fichier et la 2ème fois à la fin, il va donc falloir remplir de zéros le fichier de la première écriture jusqu’à la 2ème. La documentation le stipule bien : chaque fichier doit posséder notamment une propriété Valid data length qui correspond à la longueur des données écrites dans le fichier. Cette opération, vous l’avez compris, peut prendre du temps en fonction de la longueur à initialiser. SQL Server écrit de manière aléatoire dans le fichier même lors de son initialisation. C’est la raison pour laquelle l’utilisation de cette option est très intéressante ici.
Ecriture séquentielle :
Ecriture aléatoire :
L’utilisation de procmon peut nous permettre de visualiser l’utilisation des fonctions SetEndOfFile() et SetFileValidData(). J’ai simplement créé une base de données simple avec le fichier de données TestIntantFileInitializationWith.mdf.
- Dans le cas où Instant File Initialization n’est pas activé
On ne voit ici que l’utilisation de la fonction SetEndOfFile(). Cette fonction est utilisée dans tous les cas pour fixer physiquement la fin du fichier. Dans le cas présent la fin du fichier est fixée à 10485760 octets soit 10Go.
- Dans le cas où Instant File Initialization est activé
Une fonction supplémentaire est utilisée ici SetFileValidDate() qui permet de valider la longueur des données dans le fichier mdf : ValidDataLength : 10485760 (10Go de données dans un fichier de 10Go)
David BARBARIN (Mikedavem)
MVP SQL Server