Подключение к SQL Server 2008 R2 иногда завершается ошибкой из-за «неправильного входа в систему»

Подключение к SQL Server 2008 R2 иногда завершается ошибкой из-за «неправильного входа в систему»

В состав нашего набора тестов, помимо модульных тестов, которые имитируют все и не требуют подключения к базе данных, входят интеграционные тесты, которым требуется база данных.

Интеграционные тесты необходимы, поскольку мы работаем с большим объемом устаревшего кода, и это дает нам возможность проводить высокоуровневые тесты.

УСТАНОВКА

База данных — SQL Server 2008 R2, работающая на системе Windows Server 2008 R2 со всеми последними обновлениями Windows. Как для ОС, так и для SQL Server.

Виртуальная машина, которая запускает сервер базы данных, является частью нашей инфраструктуры сборки и создается заново, конечно же, на основе образа, каждое утро в 6 утра и уничтожается в 10 вечера. Поэтому я знаю, что SQL Server Agent и Service по сутиновыйи запускается каждый день. Первая сборка происходит в 7 утра, что дает машине достаточно времени для запуска и загрузки всех служб.

Сервер базы данных настроен на разрешение неограниченного количества подключений, а также включены именованные каналы и TCP-подключения.

Подключение к базе данных осуществляется черезсапользователь.

У нас есть сокращенный снимок нашей производственной базы данных,а.мдф, который содержит все таблицы, представления, хранимые процедуры и минимальный набор данных, необходимых для выполнения тестов.

При запуске интеграционного теста настройка теста копируета.мдфв папку DATA нашей установки SQL Server какб.мдфЗатем b.mdf присоединяется к базе данных с помощью следующей команды:

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

Тесты запускаются, выполняются операции с базой данных, а при тестовом отключении тестовой установки база данных отключается, а файл b.mdf удаляется.

Для выполнения отсоединения по отдельности выполняются следующие две команды:

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

Итак, на практике у меня есть набор тестовых приспособлений со следующей компоновкой:

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

Каждая настройка создает новую базу данных, запускает все тесты и удаляет базу данных, так что следующая текстовая фикстура начинается с чистой, новой базы данных.

Всего у меня около 50 текстовых фикстур, каждая из которых содержит 10 тестов. То есть это 50 раз, когда база данных присоединяется и отсоединяется, и запускается около 500 тестов.

ПРОБЛЕМА

За последние пару недель я вижу рост числа неудачных сборок, связанных с интеграционными тестами. Я знаю, что мои тесты в порядке, потому что вся настройка отлично работает на моей локальной машине и на машинах других разработчиков. Просто сервер сборки сообщает о проблеме:

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'.

Очевидно, я погуглил, и да, логин правильный. Я знаю это, потому что не всегда один и тот же тест терпит неудачу. Если я запущу весь набор тестов 10 раз, он провалится 8 раз из 10, но тест, который сообщает о неудаче, каждый раз разный. Сообщение об ошибке то же самое, оно говорит, что он не может войти, а иногда также сообщает, чтона другом конце трубы нет процесса.

Я также проверил, включены ли именованные каналы и TCP-соединения, проверил количество разрешенных соединений, ... Я проверил файл ERRORLOG, но он не содержит ничего, напрямую связанного с моей базой данных.

Я предполагаю, что по какой-то странной причине он работает слишком быстро или слишком медленно и не может правильно присоединить или отсоединить базу данных, или проблема в вызове SINGLE_USER. Из того, что я собрал, если один тест не пройден из-за входа в систему, файл b.mdf не может быть удален, потому что файл, похоже, используется.

Итак, мой вопрос: что еще я могу попробовать? Есть ли файл журнала ошибок или конкретное сообщение, которые могут дать мне больше информации? Можно ли что-то сделать, чтобы проверить, были ли присоединение и отсоединение успешными? (Возможно ли, что неудачное отсоединение вызывает проблему со входом?) Является ли операция отсоединения асинхронной, и, следовательно, возможно ли, что она еще не завершена, когда делается следующий вызов?

решение1

Первая проблема: ошибка входа в систему.
Ваша база данных, скорее всего, еще не полностью инициализирована, когда запускаются тесты.
Вы должны отследить это в своей процедуре, простой способ сделать это — запросить основную базу данных, чтобы узнать, запущена ли и работает ли целевая база данных.

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';

Вторая проблема: отсутствие процесса на другом конце трубы.
Ошибка, которая на самом деле стоит за этим, часто скрыта, если вы не подключаетесь через TCP/IP.
Вы можете попробовать включить прямые IP-соединения, или вы можете сосредоточиться на других ошибках, вероятно, они являются причиной этой.

Связанный контент