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

Funzionalità obsolete da eliminare dalla cassetta degli attrezzi - Parte 1

Microsoft non ha l'abitudine di deprecare le cose in questi giorni, ma quando lo fanno, è per una ragione, e non è certamente perché vogliono renderti la vita più difficile. Al contrario, è quasi sempre perché hanno sviluppato modi migliori e più moderni per risolvere quegli stessi problemi.

Ma le abitudini sono difficili da rompere; chiedimi come lo so. Troppo spesso vedo persone aggrapparsi a un modo più vecchio di portare a termine un compito, anche se esiste un modo migliore.

Vorrei condividere un paio di esempi recenti che aiutano a illustrare come l'utilizzo di funzionalità obsolete di SQL Server continui a morderci. In questa prima parte voglio parlare di...

processi di sistema

La tabella di sistema sys.sysprocesses è stato sostituito in SQL Server 2005 da una serie di viste a gestione dinamica (DMV), in particolare sys.dm_exec_requests , sys.dm_exec_sessions e sys.dm_exec_connections . La documentazione ufficiale per sys.sysprocesses avverte:

Questa tabella di sistema di SQL Server 2000 è inclusa come visualizzazione per la compatibilità con le versioni precedenti. Si consiglia invece di utilizzare le visualizzazioni di sistema correnti di SQL Server. Per trovare la vista o le viste di sistema equivalenti, vedere Mapping di tabelle di sistema in viste di sistema (Transact-SQL). Questa funzionalità verrà rimossa in una versione futura di Microsoft SQL Server. Evita di utilizzare questa funzionalità nei nuovi lavori di sviluppo e pianifica di modificare le applicazioni che attualmente utilizzano questa funzionalità.

Un esempio recente

Di recente uno dei nostri team stava indagando su un problema di latenza del lettore di log. Prestiamo molta attenzione alla latenza qui, insieme a qualsiasi transazione di lunga durata, a causa dell'impatto a valle delle tecnologie che utilizzano il lettore di log, come i gruppi di disponibilità e la replica transazionale. I nostri primi avvisi vengono solitamente individuati su una dashboard che traccia la latenza del lettore di log rispetto alla durata della transazione (spiegherò i momenti in cui ho etichettato t0 e t1 a breve):

Hanno determinato, diciamo all'ora t0 , che una determinata sessione aveva una transazione aperta che bloccava il processo di lettura del registro. Per prima cosa hanno controllato l'output di DBCC INPUTBUFFER , per cercare di determinare che cosa è durata questa sessione, ma i risultati hanno semplicemente indicato che hanno emesso anche altri batch durante la transazione:

event_type       parameters   event_info
--------------   ----------   ---------------
Language Event   0            SET ROWCOUNT 0;

Nota che DBCC INPUTBUFFER ha anche un sostituto più capace nelle versioni moderne:sys.dm_exec_input_buffer . E anche se non ha un avviso di ritiro esplicito, la documentazione ufficiale per il DBCC comando ha questa leggera spinta:

A partire da SQL Server 2014 (12.x) SP2, usare sys.dm_exec_input_buffer per restituire informazioni sulle istruzioni inviate a un'istanza di SQL Server.

Dopo aver ottenuto nulla dal buffer di input, hanno interrogato sys.sysprocesses :

SELECT 
  spid, 
  [status], 
  open_tran, 
  waittime, 
  [cpu], 
  physical_io, 
  memusage, 
  last_batch
FROM sys.sysprocesses 
WHERE spid = 107;

I risultati sono stati altrettanto inutili, almeno in termini di determinazione di ciò che la sessione stava facendo per mantenere aperta la transazione e interrompere il lettore di log:

Sto evidenziando il physical_io colonna perché questo valore ha acceso una discussione sul fatto che volessero o meno rischiare di uccidere la sessione di sonno. L'idea era che, nel caso in cui tutti quegli I/O fisici fossero scritture, l'interruzione della transazione potrebbe comportare un rollback lungo e dirompente, peggiorando potenzialmente il problema. Non inserirò i tempi effettivi su questo, ma diciamo solo che si è trasformata in una conversazione prolungata e ha lasciato il sistema in questo stato dall'ora t0 al tempo t1 nel grafico sopra.

Perché questo è un problema

Il problema in questo caso specifico è che hanno passato quel tempo a contemplare una decisione basata su informazioni incomplete. Gli I/O sono letture o scritture? Se l'utente ha una transazione aperta e ha semplicemente letto molti dati, il rollback di quella transazione ha un impatto molto inferiore rispetto a se avesse cambiato molti dati. Quindi, invece di sys.sysprocesses , vediamo qual è il DMV più moderno, sys.dm_exec_sessions , può mostrarci questa sessione:

SELECT 
  session_id, 
  [status], 
  open_transaction_count, 
  cpu_time, 
  [reads], 
  writes, 
  logical_reads, 
  last_request_start_time,
  last_request_end_time
FROM sys.dm_exec_sessions 
WHERE session_id = 107;

Risultati:

Qui vediamo che sys.dm_exec_sessions suddivide l'I/O fisico separatamente in letture e scritture. Questo ci consente di prendere una decisione molto più informata, molto più rapidamente di t1 - t0 , sull'impatto di un potenziale rollback. Se l'I/O è tutto in scrittura, ea seconda di quanto è alto il numero, potremmo esitare un po' di più e magari passare il tempo a cercare di localizzare l'utente (così potremmo schiaffeggiargli le nocche o chiedere loro perché hanno una transazione aperta ). Se sappiamo che si tratta principalmente di letture, possiamo invece propendere per l'interruzione della sessione e il ripristino della transazione.

Certo, sys.sysprocesses ha dbid e waittime . Ma dbid è comunque inaffidabile e marginalmente utile, in particolare per le query tra database; ci sono informazioni molto migliori in sys.dm_tran_locks . Le informazioni sull'attesa (tempo e ultimo tipo di attesa) sono disponibili in sys.dm_exec_requests , ma informazioni molto più dettagliate sono disponibili in sys.dm_exec_session_wait_stats (aggiunto in SQL Server 2016). Una scusa che sentivo spesso era quella sys.dm_exec_sessions mancava open_tran , ma open_transaction_count è stato aggiunto nuovamente in SQL Server 2012. Quindi ci sono pochissime ragioni per pensare di usare sys.sysprocesses oggi.

Se vuoi scoprire con quale frequenza sys.sysprocesses è stato referenziato dall'ultimo riavvio di SQL Server, è possibile eseguire questa query sui contatori delle prestazioni DMV:

SELECT instance_name, cntr_value
  FROM sys.dm_os_performance_counters
  WHERE [object_name] LIKE N'%:Deprecated Features%'
    AND instance_name = N'sysprocesses' 
  ORDER BY cntr_value DESC;

Se vuoi davvero evitare di dormire stanotte, o ti piace semplicemente aggiungere costantemente all'elenco delle cose di cui ti preoccupi, rimuovi il predicato contro instance_name . Questo ti darà un'idea spaventosa e di alto livello di quante cose sono in esecuzione le tue istanze che alla fine dovrai cambiare.

Nel frattempo, vai a scaricare sp_WhoIsActive , la procedura memorizzata ultra utile di Adam Machanic per il monitoraggio e la risoluzione dei problemi dei processi di SQL Server in tempo reale. Abbiamo distribuito questa procedura memorizzata in ogni istanza nel nostro ambiente e dovresti farlo anche tu, indipendentemente dagli altri strumenti di monitoraggio di fascia alta che potresti utilizzare.

La prossima volta

Nella parte 2 parlerò un po' di SQL Server Profiler, un'applicazione che le persone usano più per familiarità che altro, senza rendersi conto di quanto possa essere pericoloso.