O que pode causar o tempo limite de uma sessão de espelhamento e o failover?

22

Temos dois servidores SQL de produção executando o SQL Server 2005 SP4 com atualização cumulativa 3. Os dois servidores são executados em máquinas físicas idênticas. DELL PowerEdge R815 com CPUs de 4 x 12 núcleos e 512 GB (sim GB) de ram, com unidades conectadas à SAN iSCSI de 10 GB para todos os bancos de dados e logs SQL. O sistema operacional é o Microsoft Windows Server 2008 R2 Enterprise Edition, com todas as atualizações de SP e Windows. A unidade do sistema operacional é uma matriz RAID 5 de unidades SAS de 3 x 72 GB de 2,5 "e 15k. A SAN é um Dell EqualLogic 6510 com unidades de SAS de 48 x 10K de 3,5", configuradas no RAID 50, divididas em várias LUNs para os 2 servidores SQL e também compartilhadas com uma máquina Exchange e vários servidores VMWare.

Temos mais de 20 bancos de dados, 11 dos quais são espelhados com alta disponibilidade usando um servidor testemunha. O servidor testemunha é uma máquina de menor potência executando uma instância do SQL Server usada apenas para fornecer serviços testemunha. O maior banco de dados espelhado tem 450 GB e gera cerca de 100-300 iops. O Database Mirroring Monitor reporta uma taxa de envio atual de 100kb a 10mb por segundo e uma sobrecarga de confirmação de espelho de (normalmente) 0 milissegundos. O servidor espelho não tem nenhum problema em acompanhar o principal.

Estamos constantemente enfrentando failovers de espelhamento. Às vezes, um único banco de dados falha, outras vezes quase todos os bancos de dados simultaneamente. Por exemplo, ontem à noite, tivemos 10 dos 11 bancos de dados com failover, o banco de dados restante permaneceu acessível até que eu fiz o failover manualmente.

Passei por várias etapas de solução de problemas para tentar identificar o problema, mas até agora não consegui resolver o problema:

1) A máquina veio com um adaptador de rede Gigabit Broadcom BCM5709C NetXtreme II de 4 portas que usamos inicialmente como a conexão de rede principal. Desde então, instalamos um adaptador de servidor de porta dupla Intel (R) PRO / 1000 PT em ambas as máquinas para eliminar a NIC como o problema.

2) Todos os bancos de dados têm um backup completo automático noturno, juntamente com um backup de log dos bancos de dados envolvidos no espelhamento. O uso do arquivo de log é monitorado e raramente fica acima de 15% usado. O arquivo de log do banco de dados principal é de 125 GB, consistindo em 159 arquivos de log virtuais com tamanho de 511 MB a 1 GB. O TempDB é por si próprio LUN e consiste em arquivos de 24 x 2 GB.

3) O log do SQL Server na testemunha mostra nenhum erro além de: A conexão de espelhamento para "TCP: //SQL02.DOMAIN.INET: 5022" atingiu o tempo limite do banco de dados "Dados" após 30 segundos sem resposta. Verifique o serviço e as conexões de rede.

O log do SQL Server nos servidores primário e secundário mostra mensagens relacionadas ao espelhamento:

A conexão de espelhamento para "TCP: //SQL01.DOMAIN.INET: 5022" atingiu o tempo limite do banco de dados "Dados" após 30 segundos sem resposta. Verifique o serviço e as conexões de rede.

O banco de dados espelhado "Dados" está alterando as funções de "PRINCIPAL" para "MIRROR" devido à sincronização de funções. (A sincronização é digitada incorretamente aqui de propósito, pois é exatamente assim que a mensagem real é exibida.)

O banco de dados espelhado "Dados" está alterando as funções de "PRINCIPAL" para "MIRROR" devido ao Failover.

O banco de dados espelhado "Dados" está alterando as funções de "MIRROR" para "PRINCIPAL" devido ao Failover do parceiro.

Os serviços do SQL Server continuam em execução e as conexões de rede parecem permanecer ativadas. Temos sempre entre 500 e 2500 sessões conectadas a cada servidor (principalmente aplicativos robóticos que se conectam às filas do service broker em um único banco de dados).

4) TCP Chimney e RSS etc estão desabilitados usando a sintaxe NET SH.

5) Executei o SQL Server 2005 Best Practices Analyzer em ambas as máquinas e não encontrei nada além do erro muito ocasional 833 do log de eventos do aplicativo, nenhum dos quais coincide com os eventos de failover:

O SQL Server encontrou 1 ocorrência (s) de solicitações de E / S, levando mais de 15 segundos para concluir no arquivo [F: \ Data.MDF] no banco de dados [Data] (9). O identificador de arquivo do sistema operacional é 0x00000000000010A0. O deslocamento da E / S longa mais recente é: 0x000007d4b10000).

6) Ocasionalmente, vemos "O cliente não pôde reutilizar uma sessão com o SPID XXX, que foi redefinida para o pool de conexões. Esse erro pode ter sido causado por uma falha de uma operação anterior. Verifique os logs de erros para ver se há falhas nas operações imediatamente antes desta mensagem de erro. . " gerado pelos dois servidores. Parece não haver mensagens "anteriores" que indiquem qualquer problema.

7) Ocasionalmente, o correio do banco de dados grava um erro no log de eventos do aplicativo:

Tipo de exceção: Microsoft.SqlServer.Management.SqlIMail.Server.Common.BaseException Mensagem: Ocorreu um erro na conexão. Motivo: o tempo limite expirou. O tempo limite decorrido antes da conclusão da operação ou o servidor não está respondendo., Parâmetros de conexão: Nome do servidor: MGSQL02, Nome do banco de dados: msdb Dados: System.Collections.ListDictionaryInternal TargetSite: Void OpenConnection (Microsoft.SqlServer.Management.Common. SqlConnectionInfo) HelpLink: NULL Origem: DatabaseMailEngine

Informações sobre StackTrace em Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.ConnectionManager.OpenConnection (SqlConnectionInfo ci) em Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.DataAccessAdapter.OpenConnection (String dbServerName, String dbName, String user, Nome de usuário da String, String password ) em Microsoft.SqlServer.Management.SqlIMail.IMailProcess.QueueItemProcesser.ProcessQueueItems (String dbName, String dbServerName, Int32lifeMinimumSec, LogLevel loggingLevel)

Eu acredito que os Timeouts estão causando o failover; o que poderia causar esses tempos limite? Obviamente, se houvesse um problema de rede real, como um cabo com defeito ou um comutador com defeito, que poderia causar perda de pacotes e, portanto, um tempo limite, no entanto, que outras coisas poderiam causar tempos limite? Bloqueio? Se o MSDB ou algum outro banco de dados do sistema tiver um tempo limite de E / S, isso pode causar o failover de espelhamento?

Obrigado por qualquer conselho!

O MSDN tem o seguinte a dizer sobre o próprio mecanismo de tempo limite :

O mecanismo de tempo limite de espelhamento

Como erros de software não são detectáveis ​​diretamente por uma instância de servidor, um erro de software pode potencialmente fazer com que uma instância de servidor aguarde indefinidamente. Para evitar isso, o espelhamento de banco de dados implementa seu próprio mecanismo de tempo limite, com base em cada instância do servidor em uma sessão de espelhamento enviando um ping em cada conexão aberta em um intervalo fixo.

Para manter uma conexão aberta, uma instância do servidor deve receber um ping nessa conexão no período de tempo limite definido, mais o tempo necessário para enviar mais um ping. O recebimento de um ping durante o período de tempo limite indica que a conexão ainda está aberta e que as instâncias do servidor estão se comunicando sobre ela. Ao receber um ping, uma instância do servidor redefine seu contador de tempo limite nessa conexão.

Se nenhum ping for recebido em uma conexão durante o período de tempo limite, uma instância do servidor considerará o tempo limite da conexão. A instância do servidor fecha a conexão de tempo limite e lida com o evento de tempo limite de acordo com o estado e o modo operacional da sessão.

netsh interface tcp show global mostra:

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

    Consultas distribuídas ad hoc 0         
    máscara de E / S de afinidade 0         
    máscara de afinidade 0         
    affinity64 máscara de E / S 0         
    affinity64 mask 0         
    Agent XPs 1         
    permitir atualizações 0         
    incrédulo ativado 0         
    limite de processo bloqueado 5         
    modo de auditoria c2 0         
    clr ativado 1         
    conformidade de critérios comuns ativada 0         
    limiar de custo para paralelismo 4         
    encadeamento de propriedade de db cruzado 0         
    limite do cursor -1        
    XPs de correio de banco de dados 1         
    idioma de texto completo padrão 1033      
    idioma padrão 0         
    rastreamento padrão ativado 1         
    não permitir resultados de gatilhos 0         
    fator de preenchimento (%) 0         
    largura de banda de rastreamento de pés (máx.) 100       
    largura de banda de rastreamento de pés (min) 0         
    ft notificar largura de banda (máx) 100       
    ft notificar largura de banda (min) 0         
    memória de criação de índice (KB) 0         
    resolução xact em dúvida 0         
    pooling leve 0         
    fechaduras 0         
    grau máximo de paralelismo 6         
    intervalo máximo de rastreamento de texto completo 4         
    memória máxima do servidor (MB) 393216    
    tamanho máximo de substituição de texto (B) 65536     
    máximo de threads de trabalho 0         
    retenção de mídia 0         
    memória mínima por consulta (KB) 2048      
    memória mínima do servidor (MB) 52427     
    gatilhos aninhados 1         
    tamanho do pacote de rede (B) 1400      
    Procedimentos de Automação Ole 1         
    objetos abertos 0         
    Tempo limite do PH 60        
    classificação pré-computada 0         
    aumento de prioridade 0         
    limite de custo do governador de consulta 0         
    espera (s) da consulta -1        
    intervalo de recuperação (min) 0         
    acesso remoto 1         
    conexões administrativas remotas 0         
    tempo limite de login remoto 20        
    proc remoto 0         
    tempo limite da consulta remota 600       
    XPs de replicação 0         
    procurar procs de inicialização 0         
    recursão do acionador do servidor 1         
    definir tamanho do conjunto de trabalho 0         
    mostrar opções avançadas 1         
    XPs SMO e DMO 1         
    XPs do SQL Mail 0         
    transformar palavras de ruído 0         
    corte de dois dígitos para o ano 2049      
    conexões de usuário 0         
    opções de usuário 4216      
    Procedimentos do Assistente da Web 0         
    xp_cmdshell 1         

Há um tempo, modifiquei manualmente o mirroring_connection_timeoutvalor de todos os bancos de dados espelhados para 30 segundos para tentar corrigir o problema; isso simplesmente aumentou a quantidade de tempo entre eventos de failover. Com a mirroring_connection_timeoutconfiguração definida no padrão de 10 segundos, vemos muito mais failovers.

Um comentário havia me pedido para garantir que o IPSec estivesse desativado, por isso estou postando o conteúdo de vários netshcomandos que exibem a configuração do IPSec do sistema operacional:

C: \> netsh ipsec dynamic mostrar tudo
Nenhuma política atribuída no momento
Políticas de modo principal não disponíveis.
Políticas de modo rápido não disponíveis.
Filtros genéricos de modo principal não disponíveis.
Filtros de modo principal específicos não disponíveis.
Filtros de modo rápido genérico não disponíveis.
Filtros de modo rápido específicos não disponíveis.
Associações de segurança IPsec MainMode não disponíveis.
Associações de segurança IPsec QuickMode não disponíveis.

Parâmetros de configuração IPsec
------------------------------
StrongCRLCheck: 1
IPsecexempt: 3

Estatísticas IPsec
----------------
Assoc ativo: 0
SAs de transferência: 0
Chave pendente: 0
Adiciona chave: 0
Exclusões de teclas: 0
ReKeys: 0
Túneis ativos: 0
Pontos de SPI incorretos: 0
Pacotes não descriptografados: 0
Pacotes não autenticados: 0
Pacotes com detecção de repetição: 0
Bytes Confidenciais Enviados: 0
Bytes Confidenciais Recebidos: 0
Bytes autenticados enviados: 0
Bytes autenticados recebidos: 0
Bytes de transporte enviados: 0
Bytes de Transporte Recebidos: 0
Bytes enviados nos túneis: 0
Bytes recebidos nos túneis: 0
Bytes descarregados enviados: 0
Bytes descarregados recebidos: 0

C: \> netsh ipsec static mostrar tudo
ERRO IPsec [05072]: nenhuma política no repositório de políticas




ATUALIZAÇÃO: 20-12-2012

Agora, mudamos nossos sistemas de produção para o SQL Server 2012. Executamos isso desde a manhã de 17 de dezembro - até o momento sem failover. No entanto, alguns dias estão dentro do que vimos nos sistemas baseados em 2005.

Em um esforço para documentar o desempenho de nossos novos sistemas, observei com sys.dm_os_wait_statsmais cuidado; e notei DBMIRROR_DBM_EVENT, que é um tipo de espera não documentado. Graham Kent, da Microsoft, tem um artigo interessante sobre a solução de problemas de failovers inesperados e esse tipo de espera. Vou recapitular suas descobertas aqui:

O cliente estava enfrentando uma enorme cadeia de bloqueio construída em um banco de dados OLTP de alto volume, onde todos os bloqueadores de cabeçalho aguardavam no DBMIRROR_DBM_EVENT. Aqui está a sequência de eventos pelos quais passei:

  1. Revise a própria cadeia de bloqueio - como ajudar aqui, tudo o que podemos ver é que estamos aguardando DBMIRROR_DBM_EVENT

  2. Revise a fonte do tipo de espera não documentada. Obviamente, você não pode fazer isso fora do MS, mas posso dizer que, no momento da escrita, esse tipo de espera representa a espera usada quando o principal está esperando o espelho fortalecer um LSN, o que significa que a transação da qual faz parte não pode confirmar . Isso imediatamente aponta bastante especificamente para o problema de que o principal não pode confirmar transações enquanto espera no espelho. Agora precisamos investigar por que o espelho não está comprometendo transações ou por que o principal não sabe se está.

  3. Revise as tabelas do sistema msdb

(a) Veja a tabela [backupset] para ver se o tamanho dos logs produzidos no momento do problema é significativamente maior que o normal. Se eles eram excepcionalmente grandes, pode ser que o espelho estivesse inundado de transações e simplesmente não conseguisse acompanhar o volume. É por isso que os manuais online dizem às vezes para desativar o espelhamento, se você precisar executar uma operação registrada excepcionalmente grande, como uma reconstrução de índice. (referência por que isso está disponível em http://technet.microsoft.com/en-us/library/cc917681.aspx ). Aqui eu usei o seguinte 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) em segundo lugar, observei os dados nas tabelas [dbm_monitor_data]. A chave aqui é localizar o período em que tivemos um problema e, em seguida, ver se éramos significativos com alterações em qualquer um dos seguintes itens:

log_flush_rate
send_queue_size
send_rate
redo_queue_size
redo_rate

Todos esses são indicadores semelhantes à parte (a), pois podem mostrar um componente ou peça de arquitetura que não estava respondendo. Por exemplo, se o send_queue começar a crescer repentinamente, mas a fila re_do não aumentar, isso implicaria que o diretor não pode enviar os registros de log para o espelho, portanto, talvez você queira ver a conectividade ou as filas do service broker lidar com as transmissões reais.

Nesse cenário específico, observamos que todos os contadores pareciam ter valores estranhos, pois havia backups de log com tamanhos normais, mas não havia alterações de status, fila de envio 0, fila de refazer 0, taxa de envio fixa e taxa fixa. taxa de refazer. Isso é muito estranho, pois implica que o DBM Monitor não pôde registrar nenhum valor de qualquer lugar durante o período do problema.

  1. Revise os logs de erro do SQL Server. Nesse caso, não houve erros ou mensagens informativas, mas em outros cenários como esse, é muito comum que erros no intervalo 1400 sejam relatados, exemplos dos quais você pode encontrar em outros lugares nos meus outros blogs de espelhamento, como este exemplo de erro 1413

  2. Revise os arquivos de rastreamento padrão - nesse cenário, não foram fornecidos os rastreamentos padrão, no entanto, eles são fontes fantásticas de informações sobre problemas no DBM, pois registram eventos de alteração de estado em todos os parceiros.

Classe de Evento de Alteração de Estado de Espelhamento de Banco de Dados

Isso geralmente oferece uma ótima imagem de cenários, como quando a conectividade de rede falhava entre um ou todos os parceiros e depois o que o estado da parceria se tornou posteriormente.

CONCLUSÕES:

Nesse cenário em particular, atualmente estou perdendo 2 pontos-chave de dados, mas, além disso, ainda posso fazer uma hipótese razoável sobre as informações acima. Certamente, podemos dizer que o bloqueio foi causado pelo fato de o DBM ter sido ativado devido a todos os bloqueadores aguardarem no tipo de espera DBMIRROR_DBM_EVENT. Como sabemos que não inundamos o espelho com uma grande operação registrada e que essa implantação normalmente é executada com êxito nesse modo, podemos excluir grandes operações incomuns. Isso significa que temos 2 candidatos em potencial nesta fase:

  1. Problemas de hardware na conectividade entre alguns ou todos os parceiros.

  2. Exaustão da CPU no servidor espelho - simplesmente incapaz de acompanhar as refazeres - a exaustão da CPU poderia ser de um processo fora do SQL Server ou fora dessa parceria espelho.

  3. Um problema com o próprio código de espelhamento (nós realmente precisaríamos de alguns despejos de memória para confirmar isso).

Com base na experiência, eu suspeito que 1 ou 2, mas eu sempre mantenho a mente aberta em torno de 3 também, agora estamos tentando coletar mais dados para analisar esse problema com mais detalhes.

Max Vernon
fonte
Outra coisa a verificar seria o IPSec. Geralmente, o IPSec pode atrasar ou bloquear a tentativa de conexão. Desative o IPSec para ver se os tempos limite param.
Robert L Davis

Respostas:

6

Parece que você pode estar ficando sem portas TCP no SQL Server. Quantas conexões você está vendo no servidor por vez?

Timeouts como esse definitivamente estariam causando o problema.

mrdenny
fonte
Obrigado pela resposta. Esse é certamente um problema que identificamos como uma causa potencial do problema. O Windows Server 2003 possui um limite pronto para uso de 5.000 chamadas portas "efêmeras", no entanto, o Windows Server 2008 R2 está configurado para usar 16.000 (eu acho) fora da caixa. Independentemente, nós definimos as duas configurações dos Servidores SQL MaxUserPort para 65534 em HKLM \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters.
Max Vernon
Acabei de marcar as duas caixas: Principal possui 1.387 portas em uso, secundária tem 682 em uso no momento. Para verificar isso, abri um prompt do cmd e digitei: netstat -n | encontre "TCP" / c
Max Vernon
O próximo passo que eu provavelmente daria seria iniciar o wireshark na testemunha e no servidor principal e aguardar o próximo tempo limite para ver o que realmente está acontecendo no nível do TCP.
mrdenny
mmmmm ... Captura de pacotes. Alguma idéia de como decifrar o fluxo tcp na porta 5022 que é o transporte de espelhamento? Sem essa informação, o Wireshark pode não me dizer muito. Vou tentar e ver o que acontece. Obrigado pela ajuda!
Max
2

Você pode verificar você sys.dm_os_schedulers? Especificamente, se work_queue_countdesvia de 0 por um tempo significativo? Isso indicaria a fome do trabalhador e explicaria muitos dos seus sintomas.

Remus Rusanu
fonte
Eu adicionei uma tabela listando a configuração do servidor. O número máximo de threads de trabalho é definido como 0, para permitir que o servidor escolha o valor apropriado. sys.dm_os_schedulersnão mostra resultados para SELECT * FROM sys.dm_os_schedulers WHERE work_queue_count > 0;- devo gravar isso a cada minuto?
Max Vernon
Você deve verificá-lo quando ocorrerem falhas.
Remus Rusanu