Назад | Перейти на главную страницу

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

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

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

НАСТРОЙКА

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

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

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

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

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

При запуске интеграционного теста тестовая установка копирует a.mdf в папку DATA нашей установки SQL Server как b.mdf. Затем 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 не может быть удален, потому что файл, похоже, уже используется.

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

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

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-соединения или сосредоточиться на других ошибках, вероятно, они являются причиной этой ошибки.