DB SQL Server diventa inutilizzabile durante la notte


9

Ieri, il mio database SQL Server andava bene. Oggi è quasi inutilizzabile - è rallentato di un fattore compreso tra cinque e venti, a seconda di quando l'ho colpito.

Alcuni dati sono stati aggiunti al server in un processo di caricamento notturno, ma nulla di simile a un volume che dovrebbe influire così tanto su un database. Circa 50.000 record di testo semplice (senza XML o altri tipi di testo).

Il server è stato riparato stamattina prima di riavviarlo. Tuttavia, nessuno degli altri nostri server di database che sono stati corredati di patch si sta comportando diversamente.

Resource Monitor sembrerebbe suggerire che il suo IO del disco è in errore. Funziona quasi al 100% della capacità sul file .mdf per tutto il tempo, anche quando nel database non accade molto. Anche l'accesso a Templog.ldf è piuttosto alto.

Nessuno qui è un DBA esperto (siamo tutti sviluppatori con una quantità variabile di competenze SQL) e siamo tutti sconcertati da quello che è successo. Abbiamo provato a eseguire sp_updatestats e spostare alcuni dei grandi indici su dischi diversi, senza risultato.

Penso che questo debba avere qualcosa a che fare con la patch: sembra troppo una coincidenza. Un collega è convinto che il carico di dati abbia causato l'aumento delle dimensioni del mdf al punto da rendere inefficienti i piani di esecuzione.

Cosa diavolo ha causato questo? Come possiamo scoprirlo e cosa possiamo fare per risolverlo?

MODIFICARE:

L'uso sp_WhoIsActivenon rivela nulla di straordinario. Registra il mio uso dello sproc e alcuni comandi di un collega che sta attualmente cercando di spostare un altro indice. Probabilmente sta trattenendo il DB in questo momento ma stava funzionando altrettanto male prima.

È la versione standard di SQL Server 2008 R2. SELECT @@VERSIONdà:

Microsoft SQL Server 2008 R2 (SP2) - 10.50.4033.0 (X64)
9 luglio 2014 16:04:25
Copyright (c) Microsoft Corporation Standard Edition (64-bit) su Windows NT 6.1 (Build 7601: Service Pack 1) (Hypervisor )

Il server ha 72 GB di RAM e tre processori quad-core da 2 GHz.

Il patching è stato applicato solo a Windows. Non ci sono stati cambiamenti diversi dalla patch.

Impostazioni selezionate:

_id     name                        value   minimum     maximum     value_in_use    description                                 is_dynamic  is_advanced
1540    min memory per query (KB)   1024    512         2147483647  1024            minimum memory per query (kBytes)           1           1
1541    query wait (s)              -1      -1          2147483647  -1              maximum time to wait for query memory (s)   1           1
1543    min server memory (MB)      0       0           2147483647  16              Minimum size of server memory (MB)          1           1
1544    max server memory (MB)      65536   16          2147483647  65536           Maximum size of server memory (MB)          1           1

AGGIORNAMENTO: Spostare indici e tabelle su diverse partizioni del disco sembra migliorare le cose. Sono ancora confuso su come avremmo potuto raggiungere un punto critico così all'improvviso con risultati così drastici.


Puoi eseguire sp_whoisactive per 5 minuti e acquisire l'output sulla tabella. Puoi scaricarlo da qui e questo mostrerà come catturare l'output nella tabella
Kin Shah,

Bene, se hai riavviato il server, ciò significa che tutti i dati memorizzati nella cache sono stati scaricati dal pool di buffer e anche tutti i tuoi piani di esecuzione memorizzati nella cache sono stati scaricati. Ciò significa che SQL Server dovrà accelerare entrambi: ogni piano di esecuzione dovrà essere ricompilato e se le statistiche sono obsolete potresti non ottenere i piani più efficienti. Significa anche che i dati dovranno essere letti in memoria dal disco, mentre prima del riavvio probabilmente ronzava insieme ai dati in memoria. Questo dovrebbe essere di breve durata.
Aaron Bertrand

@AaronBertrand È stato così per otto ore. Riavviamo regolarmente il server per le patch e non abbiamo mai notato nulla di simile prima.
Bob Tway,

1
Non utilizzare l'interfaccia utente per verificare le impostazioni di configurazione. SELECT * FROM sys.configurations;- vuoi value, value_in_usecose del genere max server memory (MB). Anche il numero di build in SELECT @@VERSION;sarebbe utile, così come se si trova in un hypervisor e se qualcosa è cambiato sull'host da ieri (o dall'ultimo riavvio di SQL Server).
Aaron Bertrand

2
Che tipo di sottosistema IO stai usando? SAN, disco locale, ecc.? C'è qualche possibilità che casualmente un disco vada male? Inoltre, alcuni dei tuoi DB sono archiviati nella stessa posizione dei file del sistema operativo? E l'ultima domanda. Parte del nostro processo prima di eseguire un aggiornamento del sistema operativo è stato quello di realizzare in anticipo un'istantanea della VM. Purtroppo la persona responsabile ha dimenticato di impegnarlo. Molto rapidamente l'intero sistema è diventato sempre più lento. Qualche possibilità che ti sia successo?
Kenneth Fisher,

Risposte:


3

Potrebbe accadere che una piccola quantità di dati raggiunga un certo limite in SQL Server per forzare un altro piano o qualcosa del genere. Questo non è improbabile. Ma il fatto che il tuo disco sembri essere pesantemente sotto servizio mi porta a un'altra conclusione.

Ci sono 2 possibili motivi di base per il tuo rallentamento.

  1. Hai aggiornato il tuo sistema e riavviato
  2. Si carica un mucchio di dati in esso

Diamo un'occhiata alla parte n. 1

È possibile che la configurazione di SQL Server sia stata interrotta. Ciò può causare seri problemi relativi alla velocità del server e all'utilizzo del disco.

Verifica in prima istanza le impostazioni di base del server. Queste impostazioni di base sono max server memory, affinity I/O mask, affinity maske max degree of parallelism. Potrebbe essere necessario abilitare le opzioni avanzate utilizzando show advanced options.

Ecco uno script completo:

-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'

Confronta il risultato con i valori documentati nei passaggi dell'installazione. Sono sempre gli stessi?

Potrebbe avere molte ragioni per cui il tuo server si comporta in modo strano. Scommetto normalmente che il tuo max server memoryè semplicemente sbagliato. Ciò causerà lo scambio permanente delle pagine di dati in SQL Server. Non può contenere tutto nella sua memoria. Ciò significa che deve leggere le pagine dal disco, aggiornarlo, riscriverlo all'istante. Se arriva un altro aggiornamento e utilizza la stessa pagina per un aggiornamento, non può essere letto dalla memoria. Al contrario, il server deve rileggerlo dal disco. Sto solo scambiando ...

Un altro problema può essere un'alta affinità su disco o processi. Se hai utilizzato un server condiviso (SQL Server + altri servizi) con un disco dedicato per SQL Server (che può essere un caso raro, ma potrebbe essere), questo potrebbe essere il tuo problema. Il server normalmente utilizzava, ad esempio, 3 cpus per i processi e uno per l'I / O. Gli altri 12 cpus sono utilizzati per altri servizi. In questo caso la maschera di affinità è errata e utilizza ad esempio una configurazione automatica. Ciò significa che il server utilizza tutti i 16 core per processi e I / O in modo dinamico. Se hai processi enormi in esecuzione, possono caricare un carico enorme sul disco, che potrebbe non essere in grado di gestire. Ma in realtà, non credo che questo sia il tuo caso. Sarebbe più veloce (anche se solo un po ') se questo si applica, ma il tuo caso è un rallentamento.

Un altro problema potrebbe essere un grado troppo elevato di parallelismo. Ciò significa che hai troppi thread inattivi su un parziale di una query. Ciò potrebbe anche causare un enorme rallentamento se il parallelismo non funziona come previsto. Ma questo non descriverà il tuo I / O elevato in totale.

Ora diamo un'occhiata anche alla parte n. 2

Carichi un mucchio di righe nel tuo sistema. Anche se si tratta di un lavoro regolare, potrebbe sollevare un limite in cui i piani di query aumentano. È possibile che l'inserimento in combinazione con SQL Server produca questo comportamento.

Hai detto che hai già provato a migrare i tuoi indici su un altro disco, il che sembra aiutare. Questo può essere successo solo per il fatto che hai diviso il carico su due dischi diversi.

È possibile che i tuoi indici siano stati fratturati, che i tuoi piani siano stati fratturati o che le tue statistiche siano appena obsolete.

1. consente di controllare l'ultimo aggiornamento delle statistiche È possibile farlo manualmente tramite l'interfaccia per ogni singolo elemento statistico. Quale sarebbe un dolore. Oppure puoi provare questo codice:

SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes

Questo ti darà informazioni complete su ogni indice (e heap) e le statistiche dietro di essi. Anche se eseguito sp_updatestats, ciò non significa che le statistiche siano state aggiornate. La parte in cui un aggiornamento è piuttosto complicata, anche se si esegue sp_updatestatso anche se auto update statisticsè abilitata, le statistiche non verranno aggiornate appena in tempo. Ecco alcuni spunti, quando è necessario / generato un aggiornamento:

  • Una tabella vuota ottiene una o più righe
  • Una tabella con più di 500 righe aggiorna il 20% + 500 righe aggiuntive e successivamente è stato inserito un inserto
  • Quando sono state modificate 500 righe in una tabella che contiene meno di 500 righe

Ciò significa che le tue statistiche potrebbero essere obsolete anche se esegui l'aggiornamento.

Puoi dare un'occhiata alla query sopra. Se trovi alcune statistiche piuttosto vecchie in alcune tabelle, potresti voler eseguire un aggiornamento statistico manuale per questa tabella:

UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN

Dopodiché, potresti voler dare un calcio al culo al tuo server per buttare via tutti i vecchi piani.

DBCC FREEPROCCACHE 

Se vuoi solo pulire tutte le cache, potresti invece eseguire questo:

DBCC FREESYSTEMCACHE ('ALL')

Questo pulirà tutte le cache, non solo la cache del piano. Normalmente avviserei di usarlo su un server di produzione in fase di produzione. Ma poiché il tuo server non funziona attualmente, non puoi danneggiarli troppo. Potrebbe rallentare per alcuni secondi forse 1-2 minuti in quanto ha bisogno di ricostruire tutte le cache, ma dopo dovrebbe eseguire i piani corretti.

Un altro motivo possono essere indici totalmente frammentati. Questo può essere verificato su tutto il server usando questa istruzione:

SELECT * 
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)

Se la frammentazione è molto elevata, potrebbe essere necessario riorganizzarla (frammentazione <20%) o ricostruirla completamente (> 20%). Ciò potrebbe richiedere una maggiore pressione sul disco e causare problemi. D'altra parte, se gli indici sono così negativi, probabilmente aiuterebbe alla fine più di quanto faccia male.

Oltre a questi due motivi, potrebbe esserci ancora un terzo problema

Forse il tuo server è probabilmente configurato, non hai modificato alcun codice in questo momento, hai appena aggiunto alcune righe. Tutte le statistiche vengono aggiornate e tutte le cache vengono ricostruite. Tutti i tuoi indici sono riorganizzati nel modo in cui ne hai bisogno, ma comunque non funziona nulla. È possibile che tu abbia raggiunto il limite di memoria disponibile nei tuoi processi. Forse hai bisogno di più. Puoi semplicemente verificare se esiste un processo che tenta di ottenere più memoria di quella che hai.

Puoi verificarlo usando questo comando:

SELECT * FROM sys.dm_exec_query_memory_grants

Ti fornirà un elenco di tutte le sessioni che consumano memoria. Potrebbe esserci qualche query che è ancora in attesa di ottenere memoria. Queste query possono essere facilmente filtrate. Tutte le sessioni dove granted_memory_kb IS NULL. Queste sono sessioni che richiedono memoria ma non la ottengono. Un'altra cosa può essere una memoria garantita che potrebbe essere troppo bassa. Puoi confrontare le colonne requested_memory_kbcon granted_memory_kb. Richiesto mostra la quantità di memoria necessaria per l'esecuzione ottimale del processo mentre concesso mostra la memoria abilitata per il processo. Se un processo ha bisogno di 2 GB per essere eseguito ma ottiene solo 2 MB ... potresti averlo da solo. ;-)

Un altro modo è controllare RESSOURCE_SEMAPHORE:

SELECT * FROM sys.dm_exec_query_resource_semaphore

Puoi dare un'occhiata al waiter_counte al grantee_count. Se il cameriere è superiore a 0, hai una pressione nella memoria, che può causare lo scambio e la pressione del disco vista da te nel perfmon.


0

Oltre ai possibili guasti dell'unità, controllare lo stato del sottosistema RAID. Abbiamo visto qualcosa di simile e si è scoperto che la batteria sul controller RAID si è guastata, quindi non c'era cache di scrittura disponibile: tutte le scritture dovevano andare direttamente sul disco. Una nota a margine: potremmo sentire il sistema fermarsi mentre RDC ci entra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.