SQL Server 2008 R2 連接有時會因“登錄錯誤”而失敗
作為我們測試套件的一部分,在模擬所有內容且不需要數據庫連接的單元測試旁邊,我們還有需要數據庫的集成測試。
集成測試是必需的,因為我們正在處理大量遺留程式碼,它為我們提供了執行高級測試的可能性。
設置
該數據庫是 SQL Server 2008 R2,在具有所有最新 Windows 更新的 Windows Server 2008 R2 系統上執行。適用於作業系統和 SQL Server。
執行數據庫伺服器的虛擬機是我們建構基礎架構的一部分,它是基於圖像新創建的,當然,每天早上 6 點,晚上 10 點銷毀。所以我知道 SQL Server 代理和服務本質上是新的並且每天都在啟動。第一次建構發生在早上 7 點,這讓機器有足夠的時間來啟動和載入所有服務。
數據庫伺服器配置為允許無限數量的連接,並啟用命名管道和 TCP 連接。
到數據庫的連接是由sa使用者建立的。
我們有一個生產數據庫的精簡快照a.mdf,其中包含執行測試所需的所有表、視圖、儲存過程和最少的數據集。
當集成測試執行時,測試設置將a.mdf 作為 b.mdf**複製到我們的 SQL Server 安裝的 DATA 文件夾中。然後使用以下命令將 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'.
顯然,我用Google搜尋,是的,登錄是正確的。我知道這一點,因為失敗的測試並不總是相同的。如果我執行整個測試套件 10 次,它將失敗 10 次中的 8 次,但每次報告失敗的測試都不同。錯誤資訊是一樣的,說它無法登錄,有時它還報告管道的另一端沒有程序。
我還檢查了命名管道和 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 連接,或者您可以專注於其他錯誤,這很可能是導致此錯誤的原因。