Per quanto popolari siano i servizi cloud al giorno d'oggi, c'è ancora una buona parte delle distribuzioni locali di SQL Server che richiedono ancora i nostri servizi per supportarle. Una delle aree delle configurazioni in locale che dobbiamo tenere d'occhio è l'archiviazione, proprio dove vengono salvati i dati.
Ti presenterò una stored procedure per visualizzare le informazioni sullo spazio di archiviazione delle chiavi all'interno della tua istanza di SQL Server.
Considerazioni iniziali
- Assicurati che l'account che esegue questa stored procedure disponga di privilegi sufficienti.
- Gli oggetti del database (tabella del database e stored procedure) verranno creati all'interno del database selezionato al momento dell'esecuzione dello script, quindi scegliere con attenzione.
- Lo script è realizzato in modo da poter essere eseguito più volte senza ricevere un errore. Per la stored procedure, ho utilizzato l'istruzione CREATE OR ALTER PROCEDURE, disponibile da SQL Server 2016 SP1.
- Sentiti libero di cambiare il nome degli oggetti di database creati.
- Quando scegli di rendere persistenti i dati restituiti dalla stored procedure, la tabella di destinazione verrà prima troncata in modo che venga archiviato solo il set di risultati più recente.
- Tieni presente che questa soluzione non ha senso nelle implementazioni cloud in cui il provider cloud gestisce le cose per te e tu non hai accesso al file system.
Come utilizzare la stored procedure?
- Copia e incolla il codice TSQL (disponibile in questo articolo).
- L'SP prevede 2 parametri:
- @persistData:"Y" se il DBA desidera salvare l'output in una tabella di destinazione e "N" se il DBA desidera solo vedere direttamente l'output.
- @driveDetail:sebbene facoltativo, se si passa una lettera di unità, il parametro @persistData non avrà alcun effetto.
Campi presentati e loro significato
- guida: la lettera di unità che contiene i file di dati per l'istanza corrente.
- spazio_totale: la dimensione dell'unità, in GB.
- spazio_libero: la quantità di GB rimasti nell'unità.
- spazio_usato: la quantità di GB occupati da tutti i database nell'istanza.
- data_collection_timestamp: visibile solo se 'Y' viene passato al parametro @persistData e viene utilizzato per sapere quando è stato eseguito l'SP e le informazioni sono state salvate correttamente nella tabella DBA_Storage.
Test di esecuzione
Dimostrerò alcune esecuzioni della Stored Procedure in modo che tu possa farti un'idea di cosa aspettarti da essa:
EXEC GetStorageData @persistData = 'N'
Dato che l'ho eseguito in un'istanza di test in cui ho inserito tutto in C:\ drive (lo so, la peggiore pratica in assoluto), è stata restituita solo una riga. Ora, lascia che ti mostri uno screenshot dell'utilizzo del mio disco C:\, come riportato da Windows, solo per vedere se l'SP non sta bluffando in giro:
Sembra buono, per la maggior parte. Tuttavia, se dai un'occhiata più da vicino, noterai che lo "Spazio utilizzato" nella grafica dice 25 GB e l'SP dice "0,170 GB", è strano vero? Bene, il motivo è che il significato nell'SP è un po' diverso:qui riporta la quantità di GB occupati solo dai file di database, quindi tienilo a mente.
Ora, quell'output sembra un po' secco, vero? Voglio dire, non sappiamo esattamente cosa stia occupando lo spazio utilizzato riportato. È qui che entra in gioco l'altro parametro, quindi diamo un'occhiata:
EXEC GetStorageData @persistData = 'N', @driveDetail = 'C'
L'esecuzione in questo modo ti darà l'elenco di database specifici che hanno almeno 1 file di database nell'unità passata come parametro. Se sommi la colonna "spazio totale", otterrai esattamente lo stesso valore dell'output riepilogato precedente.
Fammi provare un'altra cosa per vedere cosa restituisce l'SP. Creerò un nuovo database, ma inserirò i file del database in un'altra unità che ho in giro. Chiamo il database "test" e lo inserirò nell'unità S:\.
Quindi ora l'SP emette anche quella guida nel set di risultati. Ma ancora, vediamo cosa succede se lanciamo il parametro @driveDetail con 'S' come valore:
Bingo, riporta il database "test" che ho creato con la dimensione che ho scelto (1 GB per il file di dati e 8 MB per il file di registro delle transazioni).
Query laterali
Ora, per fornire più valore al DBA, ho preparato alcune query che possono aiutarti a ottenere informazioni utili dai dati persistenti nella tabella.
*Query per trovare database con almeno 1 file di dati ospitato nell'unità C:\.
SELECT * FROM DBA_Storage WHERE drive = 'C:\';
*Query per visualizzare l'elenco delle unità ordinate per spazio libero, dal più basso al più alto. Con questo, puoi sapere quali unità richiedono la tua attenzione il prima possibile.
SELECT * FROM DBA_Storage ORDER BY free_space;
*Query per visualizzare l'elenco delle unità ordinate per spazio_utilizzato, dal più alto al più basso. Con questo, puoi sapere quali hanno più dati degli altri.
SELECT * FROM DBA_Storage ORDER BY used_space DESC;
Ecco il codice completo della Stored Procedure:
*All'inizio dello script, vedrai il valore predefinito che la stored procedure assume se non viene passato alcun valore per ciascun parametro.
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
Conclusione
- Puoi distribuire questo SP in ogni istanza di SQL Server supportata e implementare un meccanismo di avviso nell'intero stack di istanze supportate.
- Se implementi un lavoro dell'agente che richiede queste informazioni con relativa frequenza, puoi rimanere aggiornato in termini di esecuzione dei passaggi per occuparti dello spazio di archiviazione ogni volta che vengono raggiunte determinate soglie, all'interno dei tuoi ambienti supportati .
- Assicurati di controllare altri strumenti pubblicati qui su CodingSight.