Sql-Server

什麼會導致鏡像會話超時然後進行故障轉移?

  • September 6, 2021

我們有兩台生產 SQL Server 執行 SQL Server 2005 SP4 和累積更新 3。兩台伺服器都在相同的物理機上執行。DELL PowerEdge R815 配備 4 個 12 核 CPU 和 512GB(是 GB)記憶體,以及用於所有 SQL 數據庫和日誌的 10GB iSCSI SAN 連接驅動器。作業系統是帶有所有 SP 和 Windows 更新的 Microsoft Windows Server 2008 R2 企業版。作業系統驅動器是 3 個 72GB 2.5" 15k SAS 驅動器的 RAID 5 陣列。SAN 是具有 48 個 10K SAS 3.5" 驅動器的 Dell EqualLogic 6510,在 RAID 50 中配置,為 2 個 SQL Server 分割成各種 LUN,並且還共享一台 Exchange 機器和幾台 VMWare 伺服器。

我們有 20 多個數據庫,其中 11 個使用見證伺服器以高可用性進行鏡像。見證伺服器是一台執行 SQL Server 實例的低功率機器,除了提供見證服務之外沒有其他用途。最大的鏡像數據庫為 450GB,生成大約 100-300 iops。Database Mirroring Monitor 報告的目前發送速率約為每秒 100kb 到 10mb,鏡像送出成本(通常)為 0 毫秒。鏡像伺服器跟上主體沒有問題。

我們一直在經歷鏡像故障轉移。有時單個數據庫會進行故障轉移,有時幾乎所有數據庫都會同時進行故障轉移。例如,昨晚,我們在 11 個數據庫中進行了 10 個故障轉移,其餘的數據庫保持可訪問,直到我手動對其進行故障轉移。

我已經完成了幾個故障排除步驟來嘗試確定問題,但到目前為止無法解決問題:

  1. 該機器配備了 Broadcom BCM5709C NetXtreme II 4 埠千兆網路適配器,我們最初將其用作主要網路連接。此後,我們在兩台機器上都安裝了 Intel(R) PRO/1000 PT 雙埠伺服器適配器,以消除 NIC 的問題。
  2. 所有數據庫每晚都有自動完整備份以及鏡像所涉及的數據庫的日誌備份。日誌文件使用情況受到監控,很少使用超過 15%。主數據庫的日誌文件為 125GB,由 159 個虛擬日誌文件組成,大小從 511MB 到 1GB 不等。TempDB 位於它自己的 LUN 上,由 24 x 2GB 文件組成。
  3. 見證伺服器上的 SQL Server 日誌顯示除以下錯誤之外沒有錯誤: 到“TCP://SQL02.DOMAIN.INET:5022”的鏡像連接已在 30 秒後超時,數據庫“數據”沒有響應。檢查服務和網路連接。

主伺服器和輔助伺服器上的 SQL Server 日誌顯示與鏡像相關的消息:

到“TCP://SQL01.DOMAIN.INET:5022”的鏡像連接在 30 秒後超時,數據庫“Data”沒有響應。檢查服務和網路連接。

由於角色同步,鏡像數據庫“數據”正在將角色從“PRINCIPAL”更改為“MIRROR”。 (同步在這裡是故意拼錯的,因為這正是實際消息的顯示方式。)

由於故障轉移,鏡像數據庫“Data”正在將角色從“PRINCIPAL”更改為“MIRROR”。

由於來自合作夥伴的故障轉移,鏡像數據庫“Data”正在將角色從“MIRROR”更改為“PRINCIPAL”。

SQL Server 服務繼續執行並且網路連接似乎保持正常。我們始終有 500 到 2500 個會話連接到每台伺服器(主要是連接到單個數據庫上的服務代理隊列的機器人應用程序)。

  1. 使用 NET SH 語法禁用 TCP 煙囪和 RSS 等。
  2. 我對兩台機器都執行了 SQL Server 2005 最佳實踐分析器,發現除了非常偶然的應用程序事件日誌錯誤 833 之外,沒有任何發現與故障轉移事件一致:

SQL Server 遇到了 1 次 I/O 請求,完成時間超過 15 秒

$$ F:\Data.MDF $$在數據庫中$$ Data $$(9)。作業系統文件句柄為 0x00000000000010A0。最新長 I/O 的偏移量為:0x000007d4b10000)。 6. 有時我們會看到“客戶端無法重用與 SPID XXX 的會話,該會話已為連接池重置。此錯誤可能是由先前的操作失敗引起的。請在此錯誤消息之前檢查錯誤日誌以查找失敗的操作。” 由兩個伺服器生成。似乎沒有表明任何問題的“早期”消息。 7. 有時,數據庫郵件會將錯誤寫入應用程序事件日誌:

異常類型:Microsoft.SqlServer.Management.SqlIMail.Server.Common.BaseException 消息:連接出錯。原因:超時。操作完成前超時時間已過或伺服器未響應。,連接參數:伺服器名稱:MGSQL02,數據庫名稱:msdb 數據:System.Collections.ListDictionaryInternal TargetSite:Void OpenConnection(Microsoft.SqlServer.Management.Common. SqlConnectionInfo) HelpLink: NULL 來源: DatabaseMailEngine

Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.DataAccessAdapter.OpenConnection 的 Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.ConnectionManager.OpenConnection(SqlConnectionInfo ci) 的 StackTrace 資訊(字元串 dbServerName,字元串 dbName,字元串使用者名,字元串密碼)在 Microsoft.SqlServer.Management.SqlIMail.IMailProcess.QueueItemProcesser.ProcessQueueItems(字元串 dbName,字元串 dbServerName,Int32 生命週期MinimumSec,LogLevel loggingLevel)

我相信超時導致故障轉移;什麼可能導致這些超時?顯然,如果存在實際的網路問題,例如電纜損壞或交換機損壞,可能會導致封包遺失並因此超時,但是還有哪些其他因素可能導致超時?阻塞?如果 MSDB 或其他一些系統數據庫出現 I/O 超時,是否會導致鏡像故障轉移?

感謝您的任何建議!

MSDN對超時機製本身有以下說法

鏡像超時機制

由於伺服器實例無法直接檢測到軟錯誤,因此軟錯誤可能會導致伺服器實例無限期地等待。為了防止這種情況,數據庫鏡像實現了自己的超時機制,基於鏡像會話中的每個伺服器實例以固定的時間間隔在每個打開的連接上發送一個 ping。

要保持連接打開,伺服器實例必須在定義的超時期限內接收對該連接的 ping,再加上再發送一個 ping 所需的時間。在超時期間接收到 ping 表示連接仍處於打開狀態,並且伺服器實例正在通過它進行通信。在接收到 ping 時,伺服器實例會在該連接上重置其超時計數器。

如果在超時期間沒有在連接上收到 ping,則伺服器實例認為連接已超時。伺服器實例關閉超時連接並根據會話的狀態和操作模式處理超時事件。

netsh interface tcp show global顯示:

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

即席分佈式查詢 0 
親和性 I/O 遮罩 0 
親和遮罩 0 
affinity64 I/O 遮罩 0 
affinity64 遮罩 0 
特工 XP 1 
允許更新 0 
敬畏啟用 0 
阻塞程序門檻值 5 
c2 審計模式 0 
clr 啟用 1 
啟用通用標準合規性 0 
並行性的成本門檻值 4 
跨數據庫所有權連結 0 
游標門檻值 -1 
數據庫郵件 XP 1 
預設全文語言 1033 
預設語言 0 
預設跟踪啟用 1 
禁止來自觸發器 0 的結果 
填充因子 (%) 0 
英尺爬行頻寬(最大)100 
英尺爬行頻寬(分鐘) 0 
ft 通知頻寬(最大)100 
ft 通知頻寬(分鐘) 0 
索引創建記憶體 (KB) 0 
不確定的確切解析度 0 
輕量級池化 0 
鎖定 0 
最大並行度 6 
最大全文爬取範圍 4 
最大伺服器記憶體 (MB) 393216 
最大文本複制大小 (B) 65536 
最大工作執行緒 0 
媒體保留 0 
每個查詢的最小記憶體 (KB) 2048 
最小伺服器記憶體 (MB) 52427 
嵌套觸發器 1 
網路數據包大小 (B) 1400 
Ole 自動化程序 1 
打開對象 0 
PH 超時(秒) 60 
預計算等級 0 
優先級提升 0 
查詢州長成本限制 0 
查詢等待(秒)-1 
恢復間隔(分鐘) 0 
遠端訪問 1 
遠端管理員連接 0 
遠端登錄超時(秒) 20 
遠端 proc trans 0 
遠端查詢超時(秒)600 
複製 XP 0 
掃描啟動過程 0 
伺服器觸發遞歸 1 
設置工作集大小 0 
顯示高級選項 1 
SMO 和 DMO XP 1 
SQL 郵件 XP 0 
變換雜訊詞 0 
兩位數年份截止日期 2049 
使用者連接 0 
使用者選項 4216 
網路助手程序 0 
xp_cmdshell 1 

前段時間,我手動將mirroring_connection_timeout所有鏡像數據庫的值修改為 30 秒以嘗試修復問題;這只是增加了故障轉移事件之間的時間。將mirroring_connection_timeout設置設置為預設值 10 秒,我們會看到更多的故障轉移。

有評論要求我確保禁用 IPSec,因此我發布了幾個netsh顯示作業系統 IPSec 配置的命令的內容:


C:\>netsh ipsec 動態顯示所有
目前沒有分配策略
主模式策略不可用。
快速模式策略不可用。
通用主模式過濾器不可用。
特定的主模式過濾器不可用。
通用快速模式過濾器不可用。
特定的快速模式過濾器不可用。
IPsec MainMode 安全關聯不可用。
IPsec QuickMode 安全關聯不可用。

IPsec 配置參數
------------------------------
強CRL檢查:1
IPsecexempt : 3

IPsec 統計資訊
----------------
活躍協會:0
解除安裝 SA:0
待處理密鑰:0
關鍵添加:0
鍵刪除:0
重新密鑰:0
活動隧道:0
錯誤的 SPI Pkts : 0
Pkts 未解密:0
Pkts 未通過身份驗證:0
帶重放檢測的 Pkts : 0
發送的機密字節數:0
收到的機密字節:0
發送的認證字節數:0
收到的經過驗證的字節數:0
發送的傳輸字節數:0
收到的傳輸字節數:0
在隧道中發送的字節數:0
在隧道中接收的字節數:0
已解除安裝的已發送字節數:0
收到的解除安裝字節數:0

C:\>netsh ipsec 靜態顯示所有
ERR IPsec[05072]:策略儲存中沒有策略

更新:2012-12-20

我們現在已經將我們的生產系統遷移到 SQL Server 2012 上。我們從 12 月 17 日早上開始執行它 - 到目前為止沒有故障轉移。然而,幾天的時間正好在我們看到的基於 2005 的系統的範圍內。

為了記錄我們新系統的性能,我一直在sys.dm_os_wait_stats仔細研究;並註意到DBMIRROR_DBM_EVENT,這是一種無證等待類型。Microsoft 的 Graham Kent 有一篇關於解決意外故障轉移和這種等待類型的有趣文章。我將在這裡回顧他的發現:

客戶正在經歷一個建立在大容量 OLTP 數據庫上的巨大阻塞鏈,其中所有頭部阻塞器都在等待 DBMIRROR_DBM_EVENT。以下是我經歷的一系列事件:

  1. 查看阻塞鏈本身 - 這裡有幫助,因為我們所看到的是我們正在等待 DBMIRROR_DBM_EVENT
  2. 查看未記錄的等待類型的來源。顯然你不能在 MS 之外執行此操作,但我可以說在編寫此等待類型時代表主體等待鏡像硬化 LSN 時使用的等待,這意味著它所屬的事務無法送出. 這立即非常明確地指出了主體在鏡像上等待時無法送出事務的問題。現在我們需要調查為什麼鏡像沒有送出事務或者主體為什麼不知道是否送出。
  3. 查看 msdb 系統表

(一)看

$$ backupset $$表來查看問題發生時生成的日誌大小是否明顯高於正常值。如果它們特別大,則可能是鏡像充滿了事務,根本無法跟上音量。這就是為什麼線上書籍有時會告訴您如果您需要執行異常大的記錄操作(例如重建索引)禁用鏡像。(為什麼這是在http://technet.microsoft.com/en-us/library/cc917681.aspx的參考)。這裡我使用了以下 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) 其次,我查看了表格中的數據

$$ dbm_monitor_data $$. 這裡的關鍵是找到我們遇到問題的時間範圍,然後看看我們是否在以下任何方面發生了重大變化:

log_flush_rate
send_queue_size
send_rate
redo_queue_size
redo_rate

這些都是與 (a) 部分相似的指標,因為它們可能顯示沒有響應的組件或架構。例如,如果 send_queue 突然開始增長但 re_do 隊列沒有增長,那麼這意味著主體無法將日誌記錄發送到鏡像,因此您可能需要查看連接性,或者服務代理隊列處理實際的傳輸。

在這個特定的場景中,我們注意到所有的計數器似乎都有奇怪的值,因為有正常大小的日誌備份,但沒有狀態變化,0 發送隊列,0 重做隊列,固定發送速率和固定重做率。這很奇怪,因為這意味著 DBM 監視器無法在問題期間從任何地方記錄任何值。

  1. 查看 SQL Server 錯誤日誌。在這種情況下,沒有任何錯誤或資訊消息,但是在諸如此類的其他情況下,報告 1400 範圍內的錯誤是很常見的,您可以在我的其他鏡像部落格中的其他地方找到這些範例,例如此錯誤 1413 範例
  1. 查看預設跟踪文件——在這種情況下,我沒有獲得預設跟踪,但是它們是 DBM 問題資訊的絕佳來源,因為它們記錄了所有合作夥伴的狀態更改事件。此處記錄了以下內容:

數據庫鏡像狀態改變事件類

這通常可以讓您很好地了解各種場景,例如一個或所有合作夥伴之間的網路連接失敗,以及之後合作夥伴的狀態。

結論:

在這種特殊情況下,我目前缺少 2 個關鍵數據點,但除此之外,我仍然可以對上述資訊做出合理的假設。我們當然可以說阻塞是由於 DBM 被啟用,因為阻塞器都在等待 DBMIRROR_DBM_EVENT 等待類型。由於我們知道我們沒有用大型日誌操作淹沒鏡像,並且此部署通常在此模式下執行良好,因此我們可以排除異常的大型操作。這意味著我們在這個階段有 2 個潛在的候選人:

  1. 部分或全部合作夥伴之間的連接存在硬體問題。
  2. 鏡像伺服器上的 CPU 耗盡——根本無法跟上重做——CPU 耗盡本身可能來自 SQL Server 之外的程序或此鏡像夥伴關係之外的程序。
  3. 鏡像程式碼本身存在問題(我們確實需要一些記憶體轉儲來確認這一點)。

根據經驗,我懷疑是 1 或 2,但我也始終對 3 持開放態度,我們現在正在嘗試收集更多數據以更詳細地研究這個問題。

聽起來您可能用完了 SQL Server 上的 TCP 埠。您一次看到多少個與伺服器的連接?

像這樣的超時肯定會導致問題。

你能檢查一下sys.dm_os_schedulers嗎?具體來說,是否work_queue_count在任何重要時間都偏離 0?這表明工人飢餓,並解釋了您的許多症狀。

引用自:https://dba.stackexchange.com/questions/22402