A conexão do SQL Server 2008 R2 às vezes falha com 'login incorreto'

1

Como parte de nossa suíte de testes, ao lado dos Testes de Unidade, que simulam tudo e não exigem uma conexão de banco de dados, também temos Testes de Integração, que requerem um banco de dados.

Os testes de integração são necessários porque estamos trabalhando com muito código legado e nos fornece a possibilidade de realizar testes de alto nível.

A CONFIGURAÇÃO

O banco de dados é um SQL Server 2008 R2, executado em um sistema Windows Server 2008 R2 com todas as atualizações mais recentes do Windows. Tanto para o sistema operacional quanto para o SQL Server.

A VM que executa o servidor de banco de dados faz parte da nossa infraestrutura de criação e foi criada recentemente, com base em uma imagem, é claro, todas as manhãs às 6 da manhã e destruída às 10 da noite. Então, eu sei que o Agente e o Serviço do SQL Server são essencialmente novos e iniciados todos os dias. A primeira compilação ocorre às 7h, o que dá tempo suficiente à máquina para iniciar e carregar todos os serviços.

O servidor de banco de dados está configurado para permitir um número ilimitado de conexões e as conexões de pipes nomeados e TCP estão ativadas.

A conexão com o banco de dados é feita pelo usuário sa .

Temos um resumo resumido de nosso banco de dados de produção, a.mdf , que contém todas as tabelas, exibições, procedimentos armazenados e um conjunto mínimo de dados necessários para realizar os testes.

Quando um teste de integração é executado, a configuração de teste copia a.mdf para a pasta DATA de nossa instalação do SQL Server como b.mdf . O b.mdf é então anexado ao banco de dados usando o seguinte comando:

CREATE DATABASE Foo ON (FILENAME = N'Path\To\b.mdf') FOR ATTACH

Testes são executados, executam operações de banco de dados e, na análise de teste do dispositivo de teste, o banco de dados é desanexado e o arquivo b.mdf é removido.

Os dois comandos a seguir são executados individualmente para realizar a separação:

ALTER DATABASE Foo SET SINGLE_USER WITH ROLLBACK IMMEDIATE
EXEC master.dbo.sp_detach_db @dbname = N'Foo'

Então, na prática, tenho um conjunto de dispositivos de teste com o seguinte layout:

Setup();
Test_1();
Test_2();
Test_3();
TearDown();

Cada configuração cria um novo banco de dados, executa todos os testes e remove o banco de dados para que o próximo texto seja iniciado com um banco de dados limpo e novo.

No total, tenho cerca de 50 jogos de texto, cada um contendo 10 testes. Então, isso é 50 vezes que um banco de dados é anexado e desanexado e cerca de 500 testes são executados.

O PROBLEMA

Nas últimas semanas, vejo um aumento no número de construções com falha relacionadas aos testes de integração. Eu sei que meus testes estão OK porque a configuração inteira funciona perfeitamente na minha máquina local e nas máquinas dos outros desenvolvedores. É apenas o servidor de criação que relata um problema:

SetUp Error : Namespace.Class.Method
SetUp : System.Data.SqlClient.SqlException : Cannot open database "Foo"    requested by the login. The login failed.
Login failed for user 'sa'.

Obviamente, eu pesquisei e sim, o login está correto. Eu sei disso porque nem sempre é o mesmo teste que falha. Se eu executar o conjunto de testes inteiro 10 vezes, ele falhará 8 de 10, mas o teste que relata uma falha é diferente a cada vez. A mensagem de erro é a mesma, dizendo que não pode logar e às vezes também informa que não há processo na outra ponta do canal .

Também verifiquei se o pipe nomeado e as conexões TCP estão ativadas, verifiquei o número de conexões permitidas, ... Eu verifiquei o arquivo ERRORLOG, mas ele não contém nada diretamente relacionado ao meu banco de dados.

Meu palpite é que, por algum motivo estranho, isso acontece com rapidez ou com lentidão e não é capaz de anexar ou desanexar corretamente o banco de dados, ou é a chamada SINGLE_USER que causa um problema. Pelo que eu recolhi, se um teste falhar devido ao login, o arquivo b.mdf não pode ser removido porque o arquivo parece estar em uso.

Então, minha pergunta é: há mais alguma coisa que eu possa tentar? Existe um arquivo de log de erros ou uma mensagem específica que pode me fornecer mais informações? Existe algo que eu possa fazer para verificar se a anexar e desanexar foi bem-sucedida? (É possível que um desanexamento com falha cause o problema de login?) A operação de desconexão é assíncrona e, portanto, é possível que ainda não esteja concluída quando a próxima chamada é feita?

    
por Jensen 20.05.2015 / 09:20

1 resposta

1

Primeiro problema: falha no login.
Seu banco de dados provavelmente não está totalmente inicializado ainda quando os testes são executados.
Você deve perceber isso em seu procedimento, uma maneira fácil de fazer isso é consultar o banco de dados mestre para ver se o banco de dados de destino está ativo e em execução.

IF (select name from sys.databases
where name = 'foo' and state_desc = 'ONLINE' and is_in_standby = '0') IS NOT NULL
PRINT 'database not found';

Segunda edição: nenhum processo na outra extremidade do tubo.
O erro realmente por trás disso é muitas vezes obscurecido se você não se conectar através do TCP / IP.
Você pode tentar habilitar conexões IP diretas ou pode se concentrar nos outros erros, é provável que eles estejam causando esse problema.

    
por 20.05.2015 / 11:25