Hoe populair de cloudservices tegenwoordig ook zijn, er is nog steeds een groot aantal on-premises implementaties van SQL Server waarvoor onze services nog steeds nodig zijn om ze te ondersteunen. Een van de gebieden van on-premises instellingen die we in de gaten moeten houden, is de opslag, precies daar waar de gegevens worden opgeslagen.
Ik ga u een opgeslagen procedure presenteren om belangrijke opslagruimte-informatie binnen uw SQL Server-instantie te visualiseren.
Eerste overwegingen
- Zorg ervoor dat het account dat deze opgeslagen procedure uitvoert voldoende rechten heeft.
- De database-objecten (databasetabel en opgeslagen procedure) worden gemaakt in de database die is geselecteerd op het moment dat het script wordt uitgevoerd, dus kies zorgvuldig.
- Het script is zo gemaakt dat het meerdere keren kan worden uitgevoerd zonder dat u een fout krijgt. Voor de Stored Procedure heb ik de CREATE OR ALTER PROCEDURE-instructie gebruikt, beschikbaar sinds SQL Server 2016 SP1.
- Voel je vrij om de naam van de gemaakte database-objecten te wijzigen.
- Als u ervoor kiest om gegevens die zijn geretourneerd door de opgeslagen procedure te behouden, wordt de doeltabel eerst afgekapt, zodat alleen de meest recente resultatenset wordt opgeslagen.
- Houd er rekening mee dat deze oplossing niet zinvol is in cloudimplementaties waarbij de cloudprovider dingen voor je beheert en je geen toegang hebt tot het bestandssysteem.
Hoe de opgeslagen procedure gebruiken?
- Kopieer en plak de TSQL-code (beschikbaar in dit artikel).
- De SP verwacht 2 parameters:
- @persistData:'Y' als de DBA de uitvoer in een doeltabel wil opslaan, en 'N' als de DBA de uitvoer alleen rechtstreeks wil zien.
- @driveDetail:hoewel optioneel, als u een stationsletter doorgeeft, heeft de @persistData-parameter geen enkel effect.
Gepresenteerde velden en hun betekenis
- drive: de stationsletter die gegevensbestanden voor de huidige instantie bevat.
- total_space: de grootte van de schijf, in GB's.
- free_space: het aantal GB's dat nog in de schijf zit.
- used_space: het aantal GB's dat wordt ingenomen door alle databases in de instantie.
- data_collection_timestamp: alleen zichtbaar als 'Y' wordt doorgegeven aan de parameter @persistData en wordt gebruikt om te weten wanneer de SP is uitgevoerd en de informatie met succes is opgeslagen in de tabel DBA_Storage.
Uitvoeringstests
Ik zal een paar uitvoeringen van de opgeslagen procedure demonstreren, zodat u een idee krijgt van wat u ervan kunt verwachten:
EXEC GetStorageData @persistData = 'N'
Omdat ik dit in een testexemplaar heb uitgevoerd waarin ik alles in de C:\-schijf heb gestopt (ik weet het, de slechtste praktijk ooit), werd er maar één rij geretourneerd. Laat me je nu een screenshot laten zien van het gebruik van mijn C:\-schijf, zoals gerapporteerd door Windows, om te zien of de SP niet aan het bluffen is:
Het ziet er goed uit, voor het grootste deel. Als je echter beter kijkt, zul je merken dat de "Gebruikte ruimte" in de afbeelding 25 GB zegt en de SP zegt "0, 170 GB", dat is vreemd toch? Welnu, de reden is dat de betekenis in de SP een beetje anders is:hier wordt het aantal GB's vermeld dat alleen wordt ingenomen door databasebestanden, dus houd daar rekening mee.
Nu, die output lijkt een beetje droog, nietwaar? Ik bedoel, we weten niet wat precies de gerapporteerde gebruikte ruimte inneemt. Dat is waar de andere parameter in het spel komt, dus laten we eens kijken:
EXEC GetStorageData @persistData = 'N', @driveDetail = 'C'
Als u het op deze manier uitvoert, krijgt u de lijst met specifieke databases die ten minste 1 databasebestand in de drive hebben doorgegeven als parameter. Als u de kolom "totale ruimte" optelt, krijgt u exact dezelfde waarde als de vorige samengevatte uitvoer.
Laat me nog één ding proberen om te zien wat de SP teruggeeft. Ik ga een nieuwe database maken, maar ik zal de databasebestanden op een andere schijf plaatsen die ik heb liggen. Ik noem de database "test" en ik zal deze in station S:\ plaatsen.
Dus nu voert de SP die drive ook uit in de resultatenset. Maar nogmaals, laten we eens kijken wat er gebeurt als we de parameter @driveDetail gooien met 'S' als waarde:
Bingo, het rapporteert de 'test'-database die ik heb gemaakt met de grootte die ik heb gekozen (1 GB voor het gegevensbestand en 8 MB voor het transactielogbestand).
Sidequery's
Om de DBA meer waarde te bieden, heb ik een paar vragen opgesteld die u kunnen helpen om nuttige informatie te verkrijgen uit de gegevens die in de tabel staan vermeld.
*Query om databases te vinden met ten minste 1 gegevensbestand gehost in C:\ drive.
SELECT * FROM DBA_Storage WHERE drive = 'C:\';
*Query om de lijst met schijven te visualiseren, gesorteerd op vrije ruimte, van laag naar hoog. Hiermee weet u zo snel mogelijk welke schijven uw aandacht nodig hebben.
SELECT * FROM DBA_Storage ORDER BY free_space;
*Query om de lijst met schijven te visualiseren, gesorteerd op used_space, van hoog naar laag. Hiermee kun je zien welke meer gegevens hebben dan de andere.
SELECT * FROM DBA_Storage ORDER BY used_space DESC;
Hier is de volledige code van de opgeslagen procedure:
*Aan het begin van het script ziet u de standaardwaarde die de Opgeslagen Procedure aanneemt als er geen waarde wordt doorgegeven voor elke parameter.
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
Conclusie
- U kunt deze SP in elke SQL Server-instantie onder uw ondersteuning implementeren en een waarschuwingsmechanisme implementeren voor uw hele stapel ondersteunde instanties.
- Als u een agenttaak implementeert die deze informatie relatief vaak opvraagt, kunt u op de hoogte blijven wat betreft het nemen van de stappen om voor de opslag te zorgen wanneer aan bepaalde drempels wordt voldaan, binnen uw ondersteunde omgeving(en) .
- Zorg ervoor dat u meer tools bekijkt die hier op CodingSight zijn gepubliceerd.