Cosa può causare il timeout di una sessione di mirroring e il failover?


22

Abbiamo due server SQL di produzione che eseguono SQL Server 2005 SP4 con aggiornamento cumulativo 3. Entrambi i server funzionano su macchine fisiche identiche. DELL PowerEdge R815 con 4 CPU core 12 x e 512 GB (sì GB) di RAM, con unità SAN SAN iSCSI da 10 GB per tutti i database e i log SQL. Il sistema operativo è Microsoft Windows Server 2008 R2 Enterprise Edition con tutti gli aggiornamenti di SP e Windows. L'unità del sistema operativo è un array RAID 5 di 3 unità SAS da 2,5 "15k da 2,5". SAN è una Dell EqualLogic 6510 con 48 unità SAS da 10 "da 10", configurata in RAID 50, suddivisa in vari LUN per i 2 server SQL e condivisa con una macchina Exchange e diversi server VMWare.

Abbiamo oltre 20 database, 11 dei quali sono sottoposti a mirroring con elevata disponibilità utilizzando un server di controllo. Il server di controllo è un computer con potenza inferiore che esegue un'istanza di SQL Server utilizzata esclusivamente per fornire servizi di controllo. Il più grande database con mirroring è di 450 GB e genera circa 100-300 iops. Database Mirroring Monitor riporta una velocità di invio corrente compresa tra 100kb e 10mb al secondo e un overhead di commit del mirroring (in genere) di 0 millisecondi. Il server mirror non ha problemi a stare al passo con il principale.

Stiamo costantemente sperimentando failover del mirroring. A volte un singolo database eseguirà il failover, altre volte quasi tutti i database eseguiranno il failover contemporaneamente. Ad esempio, ieri sera abbiamo avuto 10 di 11 failover dei database, il restante database è rimasto accessibile fino a quando non ho eseguito il failover manualmente.

Ho provato diversi passaggi per tentare di identificare il problema, ma finora non sono stato in grado di risolvere il problema:

1) La macchina è stata fornita con una scheda di rete Gigabit Broadcom BCM5709C NetXtreme II a 4 porte che inizialmente abbiamo utilizzato come connessione di rete principale. Da allora abbiamo installato un adattatore Intel (R) PRO / 1000 PT Dual Port Server su entrambe le macchine per eliminare la scheda di rete come problema.

2) Tutti i database hanno un backup completo automatico ogni notte insieme a un backup del registro per i database coinvolti nel mirroring. L'utilizzo dei file di registro viene monitorato e raramente viene utilizzato oltre il 15%. Il file di registro per il database principale è 125 GB, costituito da 159 file di registro virtuali che variano da 511 MB a 1 GB. TempDB è sul proprio LUN ed è composto da 24 file da 2 GB.

3) Il log di SQL Server sul testimone non mostra errori diversi da: La connessione di mirroring a "TCP: //SQL02.DOMAIN.INET: 5022" è scaduta per il database "Dati" dopo 30 secondi senza risposta. Controllare il servizio e le connessioni di rete.

Il registro di SQL Server sui server primario e secondario mostra i messaggi relativi al mirroring:

La connessione di mirroring a "TCP: //SQL01.DOMAIN.INET: 5022" è scaduta per il database "Dati" dopo 30 secondi senza risposta. Controllare il servizio e le connessioni di rete.

Il database con mirroring "Dati" sta cambiando i ruoli da "PRINCIPALE" a "SPECCHIO" a causa della sincronizzazione dei ruoli. (La sincronizzazione è errata qui apposta poiché questo è esattamente il modo in cui viene visualizzato il messaggio reale.)

Il database con mirroring "Dati" sta cambiando i ruoli da "PRINCIPALE" a "SPECCHIO" a causa del Failover.

Il database con mirroring "Dati" sta cambiando i ruoli da "SPECCHIO" a "PRINCIPALE" a causa del failover del partner.

I servizi di SQL Server continuano a funzionare e le connessioni di rete sembrano rimanere attive. Abbiamo costantemente tra le 500 e le 2500 sessioni connesse a ciascun server (principalmente applicazioni robotiche che si collegano alle code dei broker di servizio su un singolo database).

4) TCP Chimney, RSS ecc. Sono disabilitati usando la sintassi NET SH.

5) Ho eseguito SQL Server 2005 Best Practices Analyzer su entrambe le macchine e non ho trovato altro che l'errore 833 del registro eventi applicazioni molto occasionale, nessuno dei quali coincide con gli eventi di failover:

SQL Server ha rilevato 1 occorrenze di richieste I / O che richiedono più di 15 secondi per essere completate nel file [F: \ Data.MDF] nel database [Dati] (9). L'handle del file OS è 0x00000000000010A0. L'offset dell'ultimo I / O lungo è: 0x000007d4b10000).

6) Occasionalmente viene visualizzato il messaggio "Il client non è stato in grado di riutilizzare una sessione con SPID XXX, che era stato ripristinato per il pool di connessioni. Questo errore potrebbe essere stato causato da un'operazione precedente non riuscita. Controllare i log degli errori per le operazioni non riuscite immediatamente prima di questo messaggio di errore ". generato da entrambi i server. Sembra che non ci siano messaggi "precedenti" che indicano alcun problema.

7) Occasionalmente la posta del database scrive un errore nel registro eventi dell'applicazione:

Tipo di eccezione: Microsoft.SqlServer.Management.SqlIMail.Server.Common.BaseException Messaggio: errore nella connessione. Motivo: timeout scaduto. Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde., Parametri di connessione: Nome server: MGSQL02, Nome database: msdb Dati: System.Collections.ListDictionaryInternal TargetSite: Void OpenConnection (Microsoft.SqlServer.Management.Common. SqlConnectionInfo) HelpLink: NULL Origine: DatabaseMailEngine

StackTrace Informazioni presso Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.ConnectionManager.OpenConnection (SqlConnectionInfo CI) al Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.DataAccessAdapter.OpenConnection (String dbServerName, String dbName, String username, password String ) in Microsoft.SqlServer.Management.SqlIMail.IMailProcess.QueueItemProcesser.ProcessQueueItems (String dbName, String dbServerName, Int32 lifeMinimumSec, LogLevel loggingLevel)

Credo che i timeout stiano causando il failover; cosa potrebbe causare questi timeout? Ovviamente se ci fosse un vero problema di rete come un cavo difettoso o un interruttore difettoso, ciò potrebbe causare la perdita di pacchetti e quindi un timeout, ma quali altre cose potrebbero causare timeout? Blocco? Se MSDB o qualche altro database di sistema avesse un timeout I / O ciò potrebbe causare il failover del mirroring?

Grazie per qualsiasi consiglio!

MSDN ha da dire sul meccanismo di timeout stesso :

Il meccanismo di timeout del mirroring

Poiché gli errori software non sono rilevabili direttamente da un'istanza del server, un errore software potrebbe causare l'attesa indefinita di un'istanza del server. Per evitare ciò, il mirroring del database implementa il proprio meccanismo di timeout, basato su ciascuna istanza del server in una sessione di mirroring che invia un ping su ogni connessione aperta a un intervallo fisso.

Per mantenere aperta una connessione, un'istanza del server deve ricevere un ping su quella connessione nel periodo di timeout definito, più il tempo necessario per inviare un altro ping. La ricezione di un ping durante il periodo di timeout indica che la connessione è ancora aperta e che le istanze del server comunicano su di essa. Alla ricezione di un ping, un'istanza del server reimposta il relativo contatore di timeout su quella connessione.

Se non viene ricevuto alcun ping su una connessione durante il periodo di timeout, un'istanza del server considera che la connessione è scaduta. L'istanza del server chiude la connessione scaduta e gestisce l'evento di timeout in base allo stato e alla modalità operativa della sessione.

netsh interface tcp show global Spettacoli:

Receive-Side Scaling State          : disabled
Chimney Offload State               : disabled
NetDMA State                        : enabled
Direct Cache Acess (DCA)            : disabled
Receive Window Auto-Tuning Level    : disabled
Add-On Congestion Control Provider  : ctcp
ECN Capability                      : disabled
RFC 1323 Timestamps                 : disabled

netsh interface ipv4 show dynamicportrange tcp

Protocol tcp Dynamic Port Range

Start Port      : 1025
Number of Ports : 64510

SELECT name, value_in_use FROM sys.configurations

    Query distribuite ad hoc 0         
    maschera I / O affinità 0         
    maschera di affinità 0         
    maschera I / O affinity64 0         
    maschera affinity64 0         
    Agent XPs 1         
    consentire aggiornamenti 0         
    timore abilitato 0         
    soglia di processo bloccata 5         
    modalità di controllo c2 0         
    clr abilitato 1         
    conformità ai criteri comuni abilitata 0         
    soglia di costo per il parallelismo 4         
    concatenamento proprietà incrociata db 0         
    soglia del cursore -1        
    Database Mail XPs 1         
    lingua full-text predefinita 1033      
    lingua predefinita 0         
    traccia predefinita abilitata 1         
    non consentire risultati dai trigger 0         
    fattore di riempimento (%) 0         
    ft larghezza di banda di scansione (max) 100       
    ft larghezza di banda di scansione (min) 0         
    ft notifica larghezza di banda (max) 100       
    ft notifica larghezza di banda (min) 0         
    indice crea memoria (KB) 0         
    risoluzione xact in dubbio 0         
    raggruppamento leggero 0         
    blocca 0         
    massimo grado di parallelismo 6         
    intervallo massimo di ricerca per indicizzazione full-text 4         
    memoria server massima (MB) 393216    
    dimensione massima di sostituzione del testo (B) 65536     
    numero massimo di thread di lavoro 0         
    fidelizzazione dei media 0         
    memoria minima per query (KB) 2048      
    memoria server min (MB) 52427     
    trigger nidificati 1         
    dimensione del pacchetto di rete (B) 1400      
    Ole Automation Procedures 1         
    oggetti aperti 0         
    Timeout PH (s) 60        
    preclassificare il rango 0         
    aumento priorità 0         
    limite costo query governatore 0         
    query attesa (s) -1        
    intervallo di recupero (min) 0         
    accesso remoto 1         
    connessioni di amministrazione remota 0         
    timeout di accesso remoto 20        
    proc proc trans 0         
    timeout (s) di query remoto 600       
    Replication XPs 0         
    scansiona i proc di avvio 0         
    ricorsione del trigger del server 1         
    set working set size 0         
    mostra opzioni avanzate 1         
    XP SMO e DMO 1         
    SQL Mail XPs 0         
    trasforma le parole di rumore 0         
    taglio anno a due cifre 2049      
    connessioni utente 0         
    opzioni utente 4216      
    Procedure Web Assistant 0         
    xp_cmdshell 1         

Qualche tempo fa, ho modificato manualmente il mirroring_connection_timeoutvalore di tutti i database con mirroring su 30 secondi per tentare di risolvere il problema; questo ha semplicemente aumentato la quantità di tempo tra gli eventi di failover. Con l' mirroring_connection_timeoutimpostazione impostata sul valore predefinito di 10 secondi, vediamo molti più failover.

Un commento mi ha chiesto di assicurarmi che IPSec sia disabilitato, quindi sto pubblicando i contenuti di diversi netshcomandi che visualizzano la configurazione IPSec del sistema operativo:

C: \> netsh ipsec dinamico mostra tutto
Nessuna politica attualmente assegnata
Politiche della modalità principale non disponibili.
Politiche Quickmode non disponibili.
Filtri generici in modalità principale non disponibili.
Filtri di modalità principale specifici non disponibili.
Filtri Quickmode generici non disponibili.
Filtri Quickmode specifici non disponibili.
Associazioni di sicurezza IPsec MainMode non disponibili.
Associazioni di sicurezza IPsec QuickMode non disponibili.

Parametri di configurazione IPsec
------------------------------
StrongCRLCheck: 1
IPsecexempt: 3

Statistiche IPsec
----------------
Assoc attivo: 0
Offload SA: 0
Chiave in sospeso: 0
Aggiunte chiave: 0
Eliminazioni chiave: 0
ReKeys: 0
Tunnel attivi: 0
Bad SPI Pkts: 0
Pkts non decrittografati: 0
Pkts non autenticato: 0
Pkts con Replay Detection: 0
Byte riservati inviati: 0
Byte riservati ricevuti: 0
Byte autenticati inviati: 0
Byte autenticati ricevuti: 0
Byte di trasporto inviati: 0
Byte di trasporto ricevuti: 0
Byte inviati nei tunnel: 0
Byte ricevuti nei tunnel: 0
Byte scaricati inviati: 0
Byte scaricati scaricati: 0

C: \> netsh ipsec static mostra tutto
IPRec ERR [05072]: Nessun criterio nel Policy Store




AGGIORNAMENTO: 20-12-2012

Ora abbiamo spostato i nostri sistemi di produzione su SQL Server 2012. Lo stiamo eseguendo dalla mattina del 17 dicembre - finora nessun failover. Tuttavia, un paio di giorni è ben all'interno di ciò che abbiamo visto con i sistemi basati sul 2005.

Nel tentativo di documentare le prestazioni dei nostri nuovi sistemi, ho esaminato sys.dm_os_wait_statspiù attentamente; e notato DBMIRROR_DBM_EVENT, che è un tipo di attesa non documentato. Graham Kent di Microsoft ha un articolo interessante sulla risoluzione dei problemi di failover imprevisti e questo tipo di attesa. Ricapitolerò qui i suoi risultati:

Il cliente stava vivendo una catena di blocchi enorme costruita su un database OLTP ad alto volume in cui tutti i bloccanti erano in attesa su DBMIRROR_DBM_EVENT. Ecco la sequenza di eventi che ho vissuto:

  1. Rivedi la catena di blocco stessa: ho un aiuto qui, poiché tutto ciò che possiamo vedere è che stiamo aspettando DBMIRROR_DBM_EVENT

  2. Rivedere l'origine per il tipo di attesa non documentato. Ovviamente non puoi farlo al di fuori di MS, ma posso dire che al momento della stesura di questo tipo di attesa rappresenta l'attesa utilizzata quando il principale è in attesa che il mirror indurisca un LSN, il che significa che la transazione di cui fa parte non può eseguire il commit . Ciò indica immediatamente in modo abbastanza specifico il problema che il principale non può eseguire il commit delle transazioni mentre è in attesa sul mirror. Ora dobbiamo indagare sul perché il mirror non sta eseguendo transazioni o perché il principale non sa se lo sia.

  3. Rivedere le tabelle di sistema msdb

(a) Guarda la tabella [backupset] per vedere se le dimensioni dei log prodotti al momento del problema sono significativamente più alte del normale. Se fossero eccezionalmente grandi, è possibile che il mirror sia stato inondato di transazioni e semplicemente non potesse tenere il passo con il volume. Questo è il motivo per cui a volte i libri online ti diranno di disabilitare il mirroring se devi eseguire un'operazione di registrazione eccezionalmente grande come una ricostruzione dell'indice. (riferimento per il motivo per cui questo è http://technet.microsoft.com/en-us/library/cc917681.aspx ). Qui ho usato il seguente TSQL

SELECT backup_set_id,backup_start_date,database_name,has_bulk_logged_data,backup_size / 1000
FROM [backupset]
where backup_start_date between '2011-01-05 14:00:00' and '2011-01-05 19:30:00'
go

select round((AVG(backup_size)/1000),0)
FROM [backupset]
where database_name = 'mydatabase'

(b) in secondo luogo ho esaminato i dati nelle tabelle [dbm_monitor_data]. La chiave qui è individuare l'intervallo di tempo in cui abbiamo avuto un problema e quindi vedere se abbiamo riscontrato cambiamenti significativi in ​​uno dei seguenti:

log_flush_rate
send_queue_size
send_rate
redo_queue_size
redo_rate

Questi sono tutti indicatori simili alla parte (a) in quanto potrebbero mostrare un componente o un pezzo di architettura che non rispondeva. Ad esempio, se send_queue inizia improvvisamente a crescere ma la coda re_do non cresce, ciò implicherebbe che il principale non può inviare i record di registro al mirror, quindi si potrebbe desiderare di esaminare la connettività o le code del broker di servizi gestire le trasmissioni effettive.

In questo particolare scenario abbiamo notato che tutti i contatori sembravano avere valori strani, in quanto c'erano backup di log in corso di dimensioni normali, ma non c'erano cambiamenti di stato, 0 coda di invio, 0 coda di ripetizione, una velocità di invio flat e una flat tasso di ripetizione. Questo è molto strano in quanto implica che il Monitor DBM non è stato in grado di registrare alcun valore da nessuna parte durante il periodo del problema.

  1. Rivedere i log degli errori di SQL Server. In questo caso non c'erano errori o messaggi informativi di sorta, ma in altri scenari come questo, è molto comune che vengano segnalati errori nell'intervallo 1400, esempi dei quali puoi trovare in altri posti nei miei altri blog di mirroring, come questo esempio di errore 1413

  2. Rivedere i file di traccia predefiniti: in questo scenario non sono state fornite le tracce predefinite, tuttavia sono fantastiche fonti di informazioni sui problemi DBM, in quanto registrano eventi di cambiamento di stato su tutti i partner.

Classe di eventi di modifica dello stato del mirroring del database

Questo ti dà spesso una visione d'insieme di scenari come quando la connettività di rete falliva tra uno o tutti i partner e poi quale stato della partnership divenne in seguito.

CONCLUSIONI:

In questo particolare scenario al momento mi mancano 2 punti chiave di dati, ma a parte questo posso ancora fare un'ipotesi ragionevole sulle informazioni di cui sopra. Possiamo certamente affermare che il blocco è stato causato dal fatto che DBM era abilitato a causa dei bloccanti tutti in attesa sul tipo di attesa DBMIRROR_DBM_EVENT. Poiché sappiamo di non aver inondato il mirror con un'operazione di grandi dimensioni registrata e che questa distribuzione normalmente funziona felicemente in questa modalità, possiamo escludere operazioni insolite di grandi dimensioni. Ciò significa che in questa fase abbiamo 2 potenziali candidati:

  1. Problemi hardware sulla connettività tra alcuni o tutti i partner.

  2. Esaurimento della CPU sul server mirror - semplicemente incapace di tenere il passo con le ripetizioni - l'esaurimento della CPU potrebbe essere esso stesso proveniente da un processo esterno a SQL Server o esterno a questa partnership mirror.

  3. Un problema con il codice di mirroring stesso (avremmo davvero bisogno di alcuni dump di memoria per confermare ciò).

In base all'esperienza di cui sospetto 1 o 2, ma ho sempre una mente aperta anche su 3, stiamo provando a raccogliere alcuni dati in più per esaminare questo problema in modo più dettagliato.


Un'altra cosa da controllare sarebbe IPSec. Spesso IPSec può ritardare o bloccare il tentativo di connessione. Disabilita IPSec per vedere se i timeout si fermano.
Robert L Davis,

Risposte:


6

Sembra che si stiano esaurendo le porte TCP su SQL Server. Quante connessioni vedi al server alla volta?

Timeout del genere causerebbero sicuramente il problema.


Grazie per la risposta. Questo è certamente un problema che abbiamo identificato come potenziale causa del problema. Windows Server 2003 ha un limite predefinito di 5.000 porte cosiddette "effimere", tuttavia Windows Server 2008 R2 è configurato per utilizzare 16.000 (credo) out of the box. Indipendentemente da ciò, abbiamo configurato le impostazioni MaxUserPort di entrambi i server SQL su 65534 in HKLM \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters.
Max Vernon,

Ho appena spuntato entrambe le caselle: il principale ha 1.387 porte in uso, il secondario ha 682 in uso in questo momento. Per verificare ciò ho aperto un prompt cmd e ho inserito: netstat -n | trova "TCP" / c
Max Vernon,

Il prossimo passo che probabilmente farei sarebbe quello di accendere wirehark sul testimone e sul server primario e attendere il timeout successivo per vedere cosa sta realmente accadendo a livello TCP.
mrdenny,

mmmmm ... Cattura di pacchetti. Qualche idea su come decifrare il flusso tcp sulla porta 5022 che è il trasporto mirroring? Senza queste informazioni, Wireshark potrebbe non dirmi molto. Lo proverò e vedrò cosa succede. Grazie per l'aiuto!
Max Vernon,


2

Puoi controllarti sys.dm_os_schedulers? In particolare, si work_queue_countdiscosta da 0 per un tempo significativo? Ciò indicherebbe la fame del lavoratore e spiegherebbe molti dei tuoi sintomi.


Ho aggiunto una tabella che elenca la configurazione del server. Max Worker Threads è impostato su 0, per consentire al server di scegliere il valore appropriato. sys.dm_os_schedulersnon mostra risultati per SELECT * FROM sys.dm_os_schedulers WHERE work_queue_count > 0;- dovrei registrarlo ogni minuto?
Max Vernon,

Dovresti verificarlo quando si verificano guasti.
Remus Rusanu,
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.