- Il registro delle transazioni è pieno
- Il database è molto lento
- L'ultimo backup risale a diversi giorni addietro
- Il sistema è bloccato e le query non funzionano
- Si verificano dei deadlock
Sfruttare i log
Un DBA deve scansionare periodicamente l'errorlog per verificare se ci sono errori, ma si tratta di un processo che può essere automatizzato creando un job di SQL Agent che viene eseguito ogni cinque minuti e che controlla se ci sono stati errori dall'ultima esecuzione. Può quindi essere utilizzata la stored procedure xp_readerrorlog per leggere il log degli errori da SQL Server SQL tramite T-SQL, inviare i risultati via e-mail, inserire il risultato in una tabella che viene mostrata su una dashboard.
-- Questo conterrà le righe CREATE TABLE #ErrorLog ( LogDate DATETIME ,ProcessInfo VARCHAR(10) ,ErrorMessage VARCHAR(Max) ) -- Dump del log degli errori nella tabella INSERT INTO #ErrorLog EXEC master.dbo.xp_readerrorlog -- Elimina tutto più vecchio di cinque minuti -- idealmente memorizzerai la data massima dell'ultima esecuzione DELETE #ErrorLog WHERE LogDate < DATEADD(mi, - 5, GETDATE()) -- Backup non riusciti SELECT * FROM #ErrorLog
Altre possibili problematiche
Il registro delle transazioni è pieno
È fondamentale assicurarsi di sapere in anticipo quando si sta per esaurire lo spazio. In caso di Transaction Log Full, è possibile seguire la procedura suggerita da Microsoft.
Il database è molto lento
Ci sono diverse cose che potrebbero provocare rallentamenti, ad esempio:
- Qualcuno ha deciso di fare un backup di un database da 1 TB durante la giornata lavorativa.
- L'aggiornamento delle statistiche dei job è ancora in esecuzione.
- Le statistiche sono obsolete e non sono state aggiornate da tempo.
- La scansione del virus causa problemi in quanto non sono stati ignorati i file del database.
- Qualcuno ha deciso di interrogare tutti i dati in una volta sola.
Con strumenti come Quest Foglight, Confio Ignite, Red Gate SQL Monitor o simili, è possibile vedere quale query è stata eseguita in quale momento, cosa ha fatto e per quanto tempo è stata eseguita. Si può utilizzare anche sp_who2, la colonna BlkBy e DBCC INPUTBUFFER per vedere cosa sta succedendo. La causa potrebbe anche essere l’hardware, occorre perciò assicurarsi che gli IO siano in buone condizioni e controllare l'eventlog per eventuali indizi.
L'ultimo backup risale a diversi giorni addietro
L'ultimo backup risale a diversi giorni addietro
La query seguente restituirà l’ultimo momento in cui è stato eseguito il backup per tutti i database o visualizzerà MAI se non è stato eseguito il backup:
SELECT s.Name AS NomeDatabase ,'Il backup del database è stato eseguito su ' + CASE WHEN MAX(b.backup_finish_date) IS NULL THEN 'MAI!!!' ELSE CONVERT(VARCHAR(12), (MAX(b.backup_finish_date)), 101) END AS UltimoTempoBackUp FROM sys.sysdatabases s LEFT OUTER JOIN msdb.dbo.backupset b ON b.database_name = s.name GROUP BY s.Name
Ecco come apparirà l'output:
NomeDatabase UltimoTempoBackUp
model Il backup del database è stato eseguito il MAI!!!
msdb Il backup del database è stato eseguito il 12/10/2012
ReportServer Il backup del database è stato eseguito il MAI!!!
Tutti i database dovrebbero sempre essere oggetto di regolare backup ed è importante controllare il file di log per eventuali backup falliti.
Il sistema è bloccato e le query non funzionano
BEGIN TRAN SELECT TOP 1 * FROM SomeTable WITH ( UPDLOCK ,HOLDLOCK )
Si otterrà un messaggio che la query è stata completata con successo.
In un'altra finestra eseguire:
SELECT TOP 1 * FROM SomeTable WITH ( UPDLOCK ,HOLDLOCK )
Questa query non restituirà nulla a meno che la prima non sia stata oggetto di committ o rollback.
Ora eseguire questa query qui sotto, la prima colonna dovrebbe avere il testo AWAITING COMMAND
SELECT sys.cmd ,sys.last_batch ,lok.resource_type ,lok.resource_subtype ,DB_NAME(lok.resource_database_id) ,lok.resource_description ,lok.resource_associated_entity_id ,lok.resource_lock_partition ,lok.request_mode ,lok.request_type ,lok.request_status ,lok.request_owner_type ,lok.request_owner_id ,lok.lock_owner_address ,wat.waiting_task_address ,wat.session_id ,wat.exec_context_id ,wat.wait_duration_ms ,wat.wait_type ,wat.resource_address ,wat.blocking_task_address ,wat.blocking_session_id ,wat.blocking_exec_context_id ,wat.resource_description FROM sys.dm_tran_locks lok JOIN sys.dm_os_waiting_tasks wat ON lok.lock_owner_address = wat.resource_address JOIN sys.sysprocesses sys ON wat.blocking_session_id = sys.spid
Le voci blocking_session_id e un session_id indicano quale session_id sta venendo bloccato. Ora si può verificare che la sessione della transazione sta bloccando l'altro ID.
Tornare alla prima finestra di comando ed eseguire un rollback:
ROLLBACK
Anche la query che aveva il secondo select dovrebbe a questo punto venire completata; se si esegue la query che controlla le attese dovrebbe essere funzionare anch’essa.
Si sarebbe potuto ottenere lo stesso risultato eseguendo sp_who2, guardando la colonna BlkBy, scoprendo cosa sta facendo quella sessione eseguendo DBCC INPUTBUFFER(session_id) con quella session_id.
Si verificano deadlock
È possibile impostare una notifica via e-mail quando si verificano deadlock. Clicca qui per la guida (in inglese).
Questo articolo è stato tratto dal blog SQL Server Code, Tips and Tricks.
di Alice Sella, pubblicato il 7 giugno 2023.