Aussi populaires que soient les services cloud de nos jours, il existe encore une bonne partie des déploiements sur site de SQL Server qui nécessitent toujours nos services pour les prendre en charge. L'un des domaines des configurations sur site que nous devons surveiller est le stockage, là où les données sont enregistrées.
Je vais vous présenter une procédure stockée pour visualiser les informations clés sur l'espace de stockage dans votre instance SQL Server.
Considérations initiales
- Assurez-vous que le compte exécutant cette procédure stockée dispose de suffisamment de privilèges.
- Les objets de la base de données (table de base de données et procédure stockée) seront créés dans la base de données sélectionnée au moment de l'exécution du script, choisissez donc avec soin.
- Le script est conçu de manière à pouvoir être exécuté plusieurs fois sans qu'une erreur ne vous soit renvoyée. Pour la procédure stockée, j'ai utilisé l'instruction CREATE OR ALTER PROCEDURE, disponible depuis SQL Server 2016 SP1.
- N'hésitez pas à modifier le nom des objets de base de données créés.
- Lorsque vous choisissez de conserver les données renvoyées par la procédure stockée, la table cible sera d'abord tronquée afin que seul le jeu de résultats le plus récent soit stocké.
- Gardez à l'esprit que cette solution n'a pas de sens dans les déploiements cloud où le fournisseur de cloud gère les choses pour vous et vous n'avez pas accès au système de fichiers.
Comment utiliser la procédure stockée ?
- Copiez et collez le code TSQL (disponible dans cet article).
- Le SP attend 2 paramètres :
- @persistData :"O" si le DBA souhaite enregistrer la sortie dans une table cible, et "N" si le DBA souhaite uniquement voir la sortie directement.
- @driveDetail :bien que facultatif, si vous transmettez une lettre de lecteur, le paramètre @persistData n'aura aucun effet.
Champs présentés et leur signification
- conduire : la lettre de lecteur qui contient les fichiers de données pour l'instance actuelle.
- espace_total : la taille du disque, en Go.
- espace_libre : le nombre de Go restant sur le lecteur.
- espace_utilisé : le nombre de Go occupés par toutes les bases de données de l'instance.
- data_collection_timestamp : visible uniquement si 'Y' est passé au paramètre @persistData, et il est utilisé pour savoir quand le SP a été exécuté et les informations ont été enregistrées avec succès dans la table DBA_Storage.
Tests d'exécution
Je vais vous montrer quelques exécutions de la procédure stockée afin que vous puissiez vous faire une idée de ce que vous pouvez en attendre :
EXEC GetStorageData @persistData = 'N'
Depuis que j'ai exécuté ceci dans une instance de test où j'ai tout bourré dans le lecteur C:\ (je sais, la pire pratique de tous les temps), une seule ligne a été renvoyée. Maintenant, laissez-moi vous montrer une capture d'écran de l'utilisation de mon lecteur C:\, tel que rapporté par Windows, juste pour voir si le SP ne bluffe pas :
Ça a l'air bien, pour la plupart. Cependant, si vous regardez de plus près, vous remarquerez que "l'espace utilisé" dans le graphique indique 25 Go et que le SP indique "0,170 Go", c'est étrange, n'est-ce pas ? Eh bien, la raison en est que la signification dans le SP est un peu différente :ici, il indique le nombre de Go occupés uniquement par les fichiers de base de données, alors gardez cela à l'esprit.
Maintenant, cette sortie semble un peu sèche, n'est-ce pas? Je veux dire, nous ne savons pas exactement ce qui prend l'espace utilisé signalé. C'est là que l'autre paramètre entre en jeu, alors vérifions-le :
EXEC GetStorageData @persistData = 'N', @driveDetail = 'C'
L'exécuter ainsi vous donnera la liste des bases de données spécifiques qui ont au moins 1 fichier de base de données dans le lecteur passé en paramètre. Si vous additionnez la colonne "espace total", cela vous donnera exactement la même valeur que la sortie résumée précédente.
Laissez-moi essayer encore une chose pour voir ce que le SP renvoie. Je vais créer une nouvelle base de données, mais je placerai les fichiers de la base de données dans un autre lecteur que j'ai autour. J'appelle la base de données "test" et je la placerai dans le lecteur S:\.
Alors maintenant, le SP produit également ce lecteur dans le jeu de résultats. Mais encore une fois, voyons ce qui se passe si nous lançons le paramètre @driveDetail avec "S" comme valeur :
Bingo, il rapporte la base de données "test" que j'ai créée avec la taille que j'ai choisie (1 Go pour le fichier de données et 8 Mo pour le fichier journal des transactions).
Requêtes annexes
Maintenant, pour offrir plus de valeur au DBA, j'ai préparé quelques requêtes qui peuvent vous aider à obtenir des informations utiles à partir des données conservées dans la table.
*Requête pour trouver des bases de données avec au moins 1 fichier de données hébergé sur le lecteur C:\.
SELECT * FROM DBA_Storage WHERE drive = 'C:\';
* Requête pour visualiser la liste des lecteurs triés par free_space, du plus bas au plus élevé. Avec cela, vous pouvez savoir quels disques nécessitent votre attention dès que possible.
SELECT * FROM DBA_Storage ORDER BY free_space;
*Requête pour visualiser la liste des disques triés par espace_utilisé, du plus élevé au plus bas. Avec cela, vous pouvez savoir lesquels ont plus de données que les autres.
SELECT * FROM DBA_Storage ORDER BY used_space DESC;
Voici le code complet de la procédure stockée :
*Au tout début du script, vous verrez la valeur par défaut que la procédure stockée assume si aucune valeur n'est transmise pour chaque paramètre.
CREATE OR ALTER PROCEDURE [dbo].[GetStorageData]
@persistData CHAR(1) = 'Y',
@driveDetail CHAR(1) = NULL
AS
BEGIN
SET NOCOUNT ON
DECLARE @command NVARCHAR(MAX)
DECLARE @Tmp_StorageInformation TABLE(
[drive] [CHAR](3) NOT NULL,
[total_space] [DECIMAL](10,3) NOT NULL,
[free_space] [DECIMAL](10,3) NOT NULL,
[used_space] [DECIMAL](10,3) NOT NULL
)
IF NOT EXISTS (SELECT * FROM dbo.sysobjects where id = object_id(N'DBA_Storage') and OBJECTPROPERTY(id, N'IsTable') = 1)
BEGIN
CREATE TABLE DBA_Storage(
[drive] [CHAR](3) NOT NULL,
[total_space] [DECIMAL](10,3) NOT NULL,
[free_space] [DECIMAL](10,3) NOT NULL,
[used_space] [DECIMAL](10,3) NOT NULL,
[data_collection_timestamp] [DATETIME] NOT NULL
)
END
IF(@driveDetail IS NOT NULL)
BEGIN
SELECT DB_NAME(mf.database_id) AS 'database',CONVERT(DECIMAL(10,3),SUM(size*8)/1024.0/1024.0) AS 'total space'
FROM sys.master_files mf
WHERE SUBSTRING(mf.physical_name,0,4) = CONCAT(@driveDetail,':\')
GROUP BY mf.database_id
RETURN
END
INSERT INTO @Tmp_StorageInformation
SELECT
drives.drive,
drives.total_space,
drives.free_space,
(SELECT CONVERT(DECIMAL(10,3),SUM(size*8)/1024.0/1024) FROM sys.master_files WHERE SUBSTRING(physical_name,0,4) = drives.drive) AS 'used_space'
FROM(
SELECT DISTINCT vs.volume_mount_point AS 'drive',CONVERT(DECIMAL(10,3),(vs.available_bytes/1048576)/1024.0) AS 'free_space',CONVERT(DECIMAL(10,3),(vs.total_bytes/1048576)/1024.0) AS 'total_space'
FROM sys.master_files mf
CROSS APPLY sys.dm_os_volume_stats(mf.database_id,mf.file_id) vs
) AS drives
IF @persistData = 'N'
SELECT * FROM @Tmp_StorageInformation
ELSE
BEGIN
TRUNCATE TABLE DBA_Storage
INSERT INTO DBA_Storage
SELECT *,GETDATE() FROM @Tmp_StorageInformation ORDER BY [drive]
END
END
Conclusion
- Vous pouvez déployer ce SP dans chaque instance SQL Server prise en charge et implémenter un mécanisme d'alerte sur l'ensemble de votre pile d'instances prises en charge.
- Si vous implémentez une tâche d'agent qui interroge ces informations relativement fréquemment, vous pouvez garder le contrôle du jeu en prenant les mesures nécessaires pour prendre soin du stockage chaque fois que certains seuils sont atteints, dans votre ou vos environnements pris en charge. .
- Assurez-vous de consulter d'autres outils publiés ici sur CodingSight.