Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Controlli di integrità proattivi di SQL Server, parte 1:spazio su disco

Alla fine del 2014, sto dando il via a una serie di post sui controlli di integrità proattivi di SQL Server, sulla base di uno che ho scritto all'inizio di quest'anno:Problemi di prestazioni:il primo incontro. In quel post, ho discusso di cosa cerco per primo durante la risoluzione di un problema di prestazioni in un ambiente sconosciuto. In questa serie di post, voglio parlare di cosa cerco quando faccio il check-in con i miei clienti a lungo termine. Forniamo un servizio DBA remoto e una delle nostre attività regolari è un "mini" audit sanitario mensile del loro ambiente. Abbiamo il monitoraggio in atto e, in genere, lavoro su progetti, quindi sono regolarmente nell'ambiente. Ma come ulteriore passaggio per assicurarci di non perdere nulla, una volta al mese esaminiamo gli stessi dati che raccogliamo nel nostro audit sanitario standard e cerchiamo qualcosa fuori dall'ordinario. Potrebbero essere molte cose, giusto? Sì! Quindi, iniziamo con lo spazio.

Ehi, spazio? Sì, spazio. Non preoccuparti, passerò ad altri argomenti. ☺

Cosa controllare

Perché dovrei iniziare con lo spazio? Perché è qualcosa che vedo spesso trascurato e se esaurisci lo spazio su disco per i file di database, diventi estremamente limitato in ciò che puoi fare nel tuo database. Hai bisogno di aggiungere dati ma non riesci a far crescere il file perché il disco è pieno? Spiacenti, ora gli utenti non possono aggiungere dati. Non si eseguono backup del registro per qualche motivo, quindi il registro delle transazioni riempie l'unità? Spiacenti, ora non puoi modificare alcun dato. Lo spazio è fondamentale. Abbiamo lavori che monitorano lo spazio libero su disco e nei file, ma continuo a verificare quanto segue per ogni controllo e confronto i valori con quelli del mese precedente:

  • Dimensione di ogni file di registro
  • Dimensione di ogni file di dati
  • Spazio libero in ogni file di dati
  • Spazio libero su ogni unità con i file di database
  • Spazio libero su ogni unità con file di backup

Crescita del file di registro

La maggior parte dei problemi che vedo relativi allo spazio su disco sono dovuti alla crescita del file di registro. La crescita si verifica in genere per uno dei due motivi:

  • Il database è in recupero COMPLETO e per qualche motivo non vengono eseguiti i backup dei log delle transazioni
  • Qualcuno esegue una singola transazione molto grande che consuma tutto lo spazio di registro esistente, costringendo il file a crescere

Ho anche visto crescere il file di registro come parte della manutenzione dell'indice. Per le ricostruzioni, ogni allocazione viene registrata e per indici di grandi dimensioni, che possono generare una quantità significativa di log. Anche con i normali backup del registro delle transazioni, il registro può comunque crescere più velocemente di quanto possano verificarsi i backup. Per gestire il registro è necessario regolare la frequenza di backup o modificare la metodologia di manutenzione dell'indice.

Devi determinare il motivo per cui il file di registro è cresciuto, il che può essere complicato a meno che tu non lo stia monitorando. Ho un lavoro che viene eseguito ogni ora per creare un'istantanea delle dimensioni e dell'utilizzo del file di registro:

USE [Baselines];
GO
 
IF (NOT EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'dbo' 
                 AND  TABLE_NAME = 'SQLskills_TrackLogSpace'))
 
BEGIN
	CREATE TABLE [dbo].[SQLskills_TrackLogSpace](
		[DatabaseName] [VARCHAR](250) NULL,
		[LogSizeMB] [DECIMAL](38, 0) NULL,
		[LogSpaceUsed] [DECIMAL](38, 0) NULL,
		[LogStatus] [TINYINT] NULL,
		[CaptureDate] [DATETIME2](7) NULL
	) ON [PRIMARY];
 
	ALTER TABLE [dbo].[SQLskills_TrackLogSpace] ADD  DEFAULT (SYSDATETIME()) FOR [CaptureDate];
 
END
 
CREATE TABLE #LogSpace_Temp (
	DatabaseName VARCHAR(100),
	LogSizeMB DECIMAL(10,2),
	LogSpaceUsed DECIMAL(10,2),
	LogStatus VARCHAR(1)
	);
 
INSERT INTO #LogSpace_Temp EXEC('dbcc sqlperf(logspace)');
 
INSERT INTO Baselines.dbo.SQLskills_TrackLogSpace 
	(DatabaseName, LogSizeMB, LogSpaceUsed, LogStatus)
	SELECT DatabaseName, LogSizeMB, LogSpaceUsed, LogStatus
	FROM #LogSpace_Temp;
 
DROP TABLE #LogSpace_Temp;

Uso queste informazioni per determinare quando il file di registro ha iniziato a crescere e inizio a esaminare i registri e la cronologia dei lavori per vedere quali informazioni aggiuntive posso trovare. La crescita del log dovrebbe essere statica:il log dovrebbe essere dimensionato in modo appropriato e gestito tramite backup (se in esecuzione in FULL recovery) e se il file deve essere più grande, devo capire perché e ridimensionarlo di conseguenza.

Se stai affrontando questo problema e non stavi già monitorando in modo proattivo gli eventi di crescita dei file, potresti comunque essere in grado di capire cosa è successo. Gli eventi di crescita automatica vengono acquisiti da SQL Server; Aaron Bertrand di SQL Sentry ne ha scritto nel blog nel 2007, dove mostra come scoprire quando si sono verificati questi eventi (purché fossero abbastanza recenti da esistere ancora nella traccia predefinita).

Dimensioni e spazio libero nei file di dati

Probabilmente hai già sentito che i tuoi file di dati dovrebbero essere predimensionati in modo che non debbano crescere automaticamente. Se segui questa guida, probabilmente non hai riscontrato l'evento in cui il file di dati cresce in modo imprevisto. Ma se non gestisci i tuoi file di dati, probabilmente la crescita si verifica regolarmente, che te ne renda conto o meno (soprattutto con le impostazioni di crescita predefinite del 10% e 1 MB).

C'è un trucco per predimensionare i file di dati:non vuoi ridimensionare un database troppo grande, perché ricorda, se esegui il ripristino, ad esempio, in un ambiente di sviluppo o QA, i file hanno le stesse dimensioni, anche se ' re non pieno di dati. Ma vuoi comunque gestire manualmente la crescita. Trovo che i DBA abbiano più difficoltà con i nuovi database. Gli utenti aziendali non hanno idea dei tassi di crescita e della quantità di dati che vengono aggiunti e quel database è un po' una mina vagante nel tuo ambiente. È necessario prestare molta attenzione a questi file finché non si ha un controllo sulle dimensioni e sulla crescita prevista. Uso una query che fornisce informazioni sulle dimensioni e sullo spazio libero:

SELECT 
    [file_id] AS [File ID],
    [type] AS [File Type],
    substring([physical_name],1,1) AS [Drive],
    [name] AS [Logical Name],
    [physical_name] AS [Physical Name],
    CAST([size] as DECIMAL(38,0))/128. AS [File Size MB], 
    CAST(FILEPROPERTY([name],'SpaceUsed') AS DECIMAL(38,0))/128. AS [Space Used MB], 
    (CAST([size] AS DECIMAL(38,0))/128) - (CAST(FILEPROPERTY([name],'SpaceUsed') AS DECIMAL(38,0))/128.) AS [Free Space],
    [max_size] AS [Max Size],
    [is_percent_growth] AS [Percent Growth Enabled],
    [growth] AS [Growth Rate],
    SYSDATETIME() AS [Current Date]
FROM sys.database_files;

Ogni mese controllo la dimensione dei file di dati e lo spazio utilizzato, quindi decido se è necessario aumentare la dimensione. Monitoro anche la traccia predefinita per gli eventi di crescita, poiché questo mi dice esattamente quando si verifica la crescita. Con l'eccezione dei nuovi database, posso sempre stare al passo con la crescita automatica dei file e gestirla manualmente. Ok, quasi sempre. Subito prima delle vacanze dell'anno scorso, il reparto IT di un cliente mi ha informato dello spazio libero insufficiente su un'unità (tenere presente questo pensiero per la prossima sezione). Ora, la notifica si basa su una soglia gratuita inferiore al 20%. Questa unità era di oltre 1 TB, quindi c'erano circa 150 GB liberi quando ho controllato l'unità. Non era ancora un'emergenza, ma avevo bisogno di capire dove fosse finito lo spazio.

Controllando i file di database per un database, ho potuto vedere che erano pieni e il mese precedente ogni file aveva oltre 50 GB gratuiti. Ho quindi analizzato le dimensioni delle tabelle e ho scoperto che in una tabella erano state aggiunte oltre 270 milioni di righe negli ultimi 16 giorni, per un totale di oltre 100 GB di dati. Risulta che c'era stata una modifica del codice e il nuovo codice registrava più informazioni del previsto. Impostiamo rapidamente un lavoro per eliminare le righe e recuperare lo spazio libero nei file (e hanno corretto il codice). Tuttavia, non sono riuscito a recuperare spazio su disco:avrei dovuto ridurre i file e non era un'opzione. Ho quindi dovuto determinare quanto spazio era rimasto su disco e decidere se era una quantità con cui mi sentivo a mio agio o meno. Il mio livello di comfort dipende dal sapere quanti dati vengono aggiunti al mese, il tasso di crescita tipico. E so solo quanti dati vengono aggiunti perché monitoro l'utilizzo dei file e posso stimare quanto spazio sarà necessario per questo mese, per quest'anno e per i prossimi due anni.

Spazio di guida

Ho accennato in precedenza che abbiamo lavori per monitorare lo spazio libero su disco. Questo si basa su una percentuale, non su un importo fisso. La mia regola generale è stata quella di inviare notifiche quando meno del 10% del disco è libero, ma per alcune unità potrebbe essere necessario impostarlo su un valore più alto. Ad esempio, con un'unità da 1 TB, ricevo una notifica quando sono disponibili meno di 100 GB. Con un'unità da 100 GB, ricevo una notifica quando sono disponibili meno di 10 GB. Con un'unità da 20 GB ... beh, vedi dove sto andando con questo. Quella soglia deve avvisarti prima che si verifichi un problema. Se ho solo 10 GB liberi su un'unità che ospita un file di registro, potrei non avere abbastanza tempo per reagire prima che si presenti come un problema per gli utenti, a seconda della frequenza con cui controllo lo spazio libero e del problema è.

È molto facile usare xp_fixeddrives per controllare lo spazio libero, ma non lo consiglierei perché non è documentato e l'uso di stored procedure estese in generale è stato deprecato. Inoltre, non segnala la dimensione totale di ciascuna unità e potrebbe non segnalare tutti i tipi di unità che i database potrebbero utilizzare. Se esegui SQL Server 2008R2 SP1 o versioni successive, puoi utilizzare il molto più conveniente sys.dm_os_volume_stats per ottenere le informazioni di cui hai bisogno, almeno sulle unità in cui sono presenti i file di database:

SELECT DISTINCT
  vs.volume_mount_point AS [Drive],
  vs.logical_volume_name AS [Drive Name],
  vs.total_bytes/1024/1024 AS [Drive Size MB],
  vs.available_bytes/1024/1024 AS [Drive Free Space MB]
FROM sys.master_files AS f
CROSS APPLY sys.dm_os_volume_stats(f.database_id, f.file_id) AS vs
ORDER BY vs.volume_mount_point;

Vedo spesso un problema con lo spazio su disco sui volumi che ospitano tempdb. Ho perso il conto delle volte in cui ho avuto clienti con una crescita di tempdb inspiegabile. A volte sono solo pochi GB; più recentemente era 200 GB. Tempdb è una bestia complicata:non c'è una formula da seguire per ridimensionarlo e troppo spesso viene posizionato su un'unità con poco spazio libero che non può gestire l'evento folle causato dallo sviluppatore principiante o dal DBA. Il dimensionamento dei file di dati tempdb richiede l'esecuzione del carico di lavoro per un ciclo aziendale "normale" per determinare quanto utilizza tempdb e quindi ridimensionarlo di conseguenza.

Di recente ho sentito un suggerimento per evitare di esaurire lo spazio su un'unità:creare un database senza dati e ridimensionare i file in modo che consumino lo spazio che si desidera "mettere da parte". Quindi, se riscontri un problema, elimina semplicemente il database e viola, hai di nuovo spazio libero. Personalmente, penso che questo crei tutti i tipi di altri problemi e non lo consiglierei. Ma se hai amministratori di archiviazione a cui non piace vedere centinaia di GB inutilizzati su un'unità, questo sarebbe un modo per far "sembrare" un'unità piena. Mi ricorda qualcosa che ho sentito dire da un mio caro amico:"Se non posso lavorare con te, lavorerò intorno a te".

Backup

Uno dei compiti principali di un DBA è proteggere i dati. I backup sono un metodo utilizzato per proteggerlo e, in quanto tali, le unità che contengono tali backup sono parte integrante della vita di un DBA. Presumibilmente stai mantenendo uno o più backup online, da ripristinare immediatamente se necessario. Il tuo runbook SLA e DR ti aiuta a stabilire quanti backup mantenere online e devi assicurarti di avere quello spazio disponibile. Ti consiglio inoltre di non eliminare i vecchi backup fino a quando il backup corrente non è stato completato correttamente. È fin troppo facile cadere nella trappola di eliminare i vecchi backup, quindi eseguire il backup corrente. Ma cosa succede se il backup corrente non riesce? E cosa succede se stai usando la compressione? Aspetta un secondo... i backup compressi sono più piccoli, giusto? Sono più piccoli, alla fine. Ma sapevi che la dimensione del file .bak di solito inizia più grande della dimensione finale? Puoi usare il flag di traccia 3042 per modificare questo comportamento, ma dovresti pensare che con i backup hai bisogno di molto spazio. Se il tuo backup è di 100 GB e stai mantenendo 3 giorni online, hai bisogno di 300 GB per i 3 giorni di backup, e quindi probabilmente una buona quantità (2 volte la dimensione attuale del database) gratis per il backup successivo. Sì, questo significa che in qualsiasi momento avrai più di 100 GB gratuiti su questa unità. Va bene. È meglio che il processo di eliminazione vada a buon fine e il processo di backup non vada a buon fine e scopra tre giorni dopo che non hai alcun backup (è successo a un cliente nel mio precedente lavoro).

La maggior parte dei database diventa più grande nel tempo, il che significa che anche i backup diventano più grandi. Non dimenticare di controllare regolarmente la dimensione dei file di backup e allocare spazio aggiuntivo secondo necessità:avere una politica "200 GB gratuiti" per un database che è cresciuto fino a 350 GB non sarà molto utile. Se i requisiti di spazio cambiano, assicurati di modificare anche tutti gli avvisi associati.

Utilizzo di Performance Advisor

Ci sono diverse query incluse in questo post che puoi utilizzare per monitorare lo spazio, se devi eseguire il tuo processo. Ma se ti capita di avere SQL Sentry Performance Advisor nel tuo ambiente, questo diventa molto più semplice con le condizioni personalizzate. Ci sono diverse condizioni di stock incluse per impostazione predefinita, ma puoi anche crearne di tue.

All'interno del client SQL Sentry, apri il Navigatore, fai clic con il pulsante destro del mouse su Gruppi condivisi (Globale) e seleziona Aggiungi condizione personalizzata → SQL Sentry. Fornire un nome e una descrizione per la condizione, quindi aggiungere un confronto numerico e modificare il tipo in Repository Query. Inserisci la domanda:

SELECT MIN(FreeSpace*100.0/Size)
  FROM SQLSentry.dbo.PerformanceAnalysisDeviceLogicalDisk;

Modifica uguale a è minore di e imposta un valore esplicito di 10. Infine, modifica la frequenza di valutazione predefinita impostandola su un valore meno frequente di ogni 10 secondi. Una volta al giorno o una volta ogni 12 ore è probabilmente un buon valore:non dovresti aver bisogno di controllare lo spazio libero più spesso di una volta al giorno, ma puoi controllarlo tutte le volte che vuoi. La schermata seguente mostra la configurazione finale:

Dopo aver fatto clic su Salva per la condizione, ti verrà chiesto se desideri assegnare azioni per la condizione personalizzata. L'opzione Invia a canali di avviso è selezionata per impostazione predefinita, ma potresti voler eseguire altre attività, come Esegui un processo, ad esempio per copiare i vecchi backup in un'altra posizione (se è l'unità con poco spazio).

Come accennato in precedenza, un valore predefinito del 10% di spazio libero per tutte le unità probabilmente non è appropriato per ogni unità nel tuo ambiente. Puoi personalizzare la query per diverse istanze e unità, ad esempio:

SELECT Alert = MAX(CASE 
  WHEN Name = N'C:' AND [FreeSpace%] < 10 THEN 1
  WHEN Name = N'S:' AND [FreeSpace%] < 25 THEN 1
  WHEN Name = N'T:' AND [FreeSpace%] < 20 THEN 1
  ELSE 0 END)
FROM 
(
  SELECT 
	d.Name, 
	d.FreeSpace * 100.0/d.Size AS [FreeSpace%]
  FROM SQLSentry.dbo.PerformanceAnalysisDeviceLogicalDisk AS d
  INNER JOIN SQLSentry.dbo.EventSourceConnection AS c
  ON d.DeviceID = c.DeviceID
  WHERE c.ObjectName = N'HANK\SQL2012' -- replace with your server/instance
) AS s;

Puoi modificare ed espandere questa query in base alle esigenze del tuo ambiente, quindi modificare il confronto nella condizione di conseguenza (valutando sostanzialmente su true se il risultato è sempre 1):

Se vuoi vedere Performance Advisor in azione, scarica una versione di prova.

Tieni presente che per entrambe queste condizioni, verrai avvisato solo una volta, anche se più unità scendono al di sotto della tua soglia. In ambienti complessi potresti preferire un numero maggiore di condizioni più specifiche per fornire avvisi più flessibili e personalizzati, piuttosto che un minor numero di condizioni "catch-all".

Riepilogo

Esistono molti componenti critici in un ambiente SQL Server e lo spazio su disco deve essere monitorato e mantenuto in modo proattivo. Con solo un po' di pianificazione, questo è semplice da fare e allevia molte incognite e una risoluzione reattiva dei problemi. Indipendentemente dal fatto che utilizzi i tuoi script o uno strumento di terze parti, assicurarsi che ci sia molto spazio libero per i file di database e i backup è un problema facilmente risolvibile e ne vale la pena.