對 SQL Server 中處於復原擱置或可疑狀態的 Always On 可用性資料庫進行疑難排解
本文說明可用性資料庫在 Microsoft Recovery Pending
Suspect
或 狀態中的可用性資料庫錯誤和限制,以及如何將資料庫還原至可用性群組中的完整功能。
原始產品版本: SQL Server 2012
原始 KB 編號: 2857849
摘要
假設 Always On 可用性群組中定義的可用性資料庫會 Recovery Pending
轉換成 SQL Server 中的 或 Suspect
狀態。 如果這種情況發生在可用性群組的主要複本上,資料庫可用性就會受到影響。 在此情況下,您無法透過用戶端應用程式存取資料庫。 此外,您無法從可用性群組卸除或移除資料庫。
例如,假設 SQL Server 正在執行,且可用性資料庫設定為 Recovery Pending
或 Suspect
狀態。 當您使用下列 SQL 腳本查詢主要複本上的動態管理檢視 (DMV)時,資料庫可能會回報 NOT_HEALTHY
為 和 RECOVERY_PENDING
狀態或 SUSPECT
狀態,如下所示:
SELECT
dc.database_name,
d.synchronization_health_desc,
d.synchronization_state_desc,
d.database_state_desc
FROM
sys.dm_hadr_database_replica_states d
JOIN sys.availability_databases_cluster dc ON d.group_database_id = dc.group_database_id
AND d.is_local = 1
database_name synchronization_health_desc synchronization_state_desc database_state_desc
-------------------- ------------------------------ ------------------------------ ---------------------
<DatabaseName> NOT_HEALTHY NOT SYNCHRONIZING RECOVERY_PENDING
(1 row(s) affected)
此外,此資料庫可能會報告為 SQL Server Management Studio 中的「未同步處理/復原暫止 」或 「可疑 」狀態。
在可用性群組中定義資料庫時,無法卸除或還原資料庫。 因此,您必須採取特定步驟來復原資料庫,並將其傳回生產環境使用。
其他相關資訊
下列內容討論各種情況下處於復原擱置狀態的可用性資料庫錯誤和限制。
資料庫狀態可防止還原資料庫
您試著執行下列 SQL 腳本來還原具有
RECOVERY
參數的資料庫:RESTORE DATABASE <DatabaseName> WITH RECOVERY
當您執行此文稿時,您會收到下列錯誤訊息,因為資料庫是在可用性群組中定義:
訊息 3104,層級 16,狀態 1,第 1 行
RESTORE 無法在databaseName <> 上運作,因為它已針對資料庫鏡像設定,或已聯結可用性群組。 如果您想要還原資料庫,請使用 ALTER DATABASE 來移除鏡像,或從其可用性群組中移除資料庫。Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE 正在異常終止。資料庫狀態可防止卸除資料庫
您試著執行下列 SQL 腳本來卸除資料庫:
DROP DATABASE <DatabaseName>
當您執行此文稿時,您會收到下列錯誤訊息,因為資料庫是在可用性群組中定義:
訊息 3752,層級 16,狀態 1,第 1 行
DatabaseName> 資料庫<目前已聯結至可用性群組。 您必須先從可用性群組中移除資料庫,才能卸除資料庫。資料庫狀態可防止從可用性群組中移除資料庫
您試著執行下列 SQL 文稿,以從可用性群組中移除資料庫:
ALTER DATABASE <DatabaseName> SET hadr OFF
當您嘗試執行此文稿時,您會收到下列錯誤訊息,因為可用性資料庫屬於主要復本:
訊息 35240,層級 16,狀態 14,第 1 行
DatabaseName <> 無法聯結至可用性群組 <AvailabilityGroupName> 或取消加入。 可用性群組的主要復本不支援這項作業。由於這個錯誤訊息,您可能會被迫故障轉移資料庫。 故障轉移資料庫之後,擁有復原暫止資料庫的複本會處於次要角色中。 在此情況下,您嘗試再次執行下列 SQL 腳稿,以從次要複本的可用性群組中移除資料庫:
ALTER DATABASE <DatabaseName> SET hadr OFF
不過,您仍然無法從可用性群組中移除資料庫,而且您會收到下列錯誤訊息,因為資料庫仍處於復原擱置中狀態:
訊息 921,層級 16,狀態 112,第 1 行
Database <DatabaseName> 尚未復原。 請在稍後重試。
當資料庫處於次要角色時的解決方案
若要解決此問題,請採取下列一般動作:
- 從可用性群組中移除當資料庫處於次要角色時裝載損毀資料庫的複本。
- 解決影響系統且可能導致資料庫失敗的任何問題。
- 將復本還原至可用性群組。
若要採取這些動作,請連線到新的主要複本,然後執行 ALTER AVAILABILITY GROUP
SQL 腳本來移除裝載失敗可用性資料庫的複本。 若要這麼做,請執行下列步驟。
這些步驟假設主要復本會先裝載損毀的資料庫。 因此,必須先進行故障轉移,才能將裝載損毀資料庫的複本轉換為次要角色。
連接到執行 SQL Server 且裝載次要複本的伺服器。
執行下列 SQL 文稿:
ALTER AVAILABILITY GROUP <AvailabilityGroupName> FAILOVER
執行下列 SQL 文稿,從可用性群組移除裝載損毀資料庫的複本:
ALTER AVAILABILITY GROUP <AvailabilityGroupName> REMOVE REPLICA ON '<SQLServerNodeName>'
解決執行 SQL Server 且可能導致資料庫失敗之伺服器上的任何問題。
將復本新增回可用性群組。
解決主要復本是可用性群組中唯一的複本
如果主要復本裝載損毀的資料庫,而且是可用性群組中唯一的工作複本,則必須卸除可用性群組。 卸除可用性群組之後,您可以從備份復原您的資料庫,或套用其他緊急復原工作來還原資料庫並恢復生產環境。
若要卸除可用性群組,請使用下列 SQL 腳本:
DROP AVAILABILITY GROUP <AvailabilityGroupName>
此時,您可以嘗試復原有問題的資料庫。 或者,您可以從上次已知的良好備份複本還原資料庫。
當您卸除可用性群組時的解決方案
當您卸除可用性群組時,接聽程序資源也會卸除,並中斷應用程式與可用性資料庫的連線。
若要將應用程式停機時間降到最低,請使用下列其中一種方法,透過接聽程式維持應用程式連線,並卸載可用性群組:
方法 1:將接聽程式與故障轉移叢集管理員中的新可用性群組(角色)產生關聯
此方法可讓您在卸除並重新建立可用性群組時維護接聽程式。
在現有可用性群組接聽程序導向連線的 SQL Server 實例上,建立新的空白可用性群組。 若要簡化此程式,請使用 Transact-SQL 命令來建立沒有次要復本或資料庫的可用性群組:
USE master GO CREATE AVAILABILITY GROUP ag FOR REPLICA ON 'sqlnode1' WITH ( ENDPOINT_URL = 'tcp://sqlnode1:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL )
啟動 [故障轉移叢集管理員],然後選取左窗格中的角色。 在列出角色的窗格中,選取原始可用性群組。
在 [資源] 索引標籤下的底部窗格中,以滑鼠右鍵按兩下可用性群組資源,然後選取 [屬性]。 選取 [ 相依性] 索引卷標,刪除接聽程式的相依性,然後選取 [ 確定]。
在資源下,以滑鼠右鍵按兩下接聽程式,選取 [更多動作],然後選取 [ 指派給其他角色]。
在 [ 將來源指派給角色 ] 對話框中,選取新的可用性群組,然後選取 [ 確定]。
在 [ 角色] 窗格中,選取新的可用性群組。 在中間窗格的 [資源] 索引標籤下,您現在應該會看到新的可用性群組和接聽程序資源。 以滑鼠右鍵按下新的可用性群組資源,然後選取 [ 屬性]。
按兩下 [ 相依性] 索引標籤,從下拉式方塊中選取接聽程式資源,然後選取 [ 確定]。
在 SQL Server Management Studio 中,使用 物件總管 連接到裝載新可用性群組主要複本的 SQL Server 實例。 選取 [ AlwaysOn 高可用性],按下新的可用性群組,然後選取 [ 可用性群組接聽程式]。 您應該會找到接聽程式。
以滑鼠右鍵按兩下接聽程式,選取 [屬性],輸入接聽程式的適當埠號碼,然後選取 [ 確定]。
這可確保使用接聽程式的應用程式仍然可以使用它來連線到裝載生產資料庫的 SQL Server 實例,而不會中斷。 原始可用性群組現在可以完全移除並重新建立。 或者,資料庫和複本可以新增至新的可用性群組。
如果您重新建立原始可用性群組,您應該將接聽程式重新指派回可用性群組角色、設定新可用性群組資源與接聽程式之間的相依性,然後將埠重新指派給接聽程式。 若要這樣做,請遵循下列步驟:
- 啟動 [故障轉移叢集管理員],然後選取左窗格中的角色。 在列出角色的窗格中,按兩下裝載接聽程式的新可用性群組。
- 在 [資源] 索引標籤下的底部中間窗格中,以滑鼠右鍵按兩下接聽程式,選取 [更多動作],然後選取 [指派給另一個角色]。 在對話框中,選擇重新建立的可用性群組,然後選取 [ 確定]。
- 在 [ 角色] 窗格中,按兩下重新建立的可用性群組。 在底部中間窗格的 [資源] 索引標籤下,您現在應該會看到重新建立的可用性群組和接聽程序資源。 以滑鼠右鍵按鍵按下重新建立的可用性群組資源,然後選取 [ 屬性]。
- 選取 [ 相依性] 索引卷標,從下拉式方塊中選取接聽程式資源,然後選取 [ 確定]。
- 在 SQL Server Management Studio 中,使用 物件總管 連接到裝載重新建立可用性群組主要複本的 SQL Server 實例。 選取 [ AlwaysOn 高可用性],按下新的可用性群組,然後選取 [ 可用性群組接聽程式]。 您應該會找到接聽程式。
- 以滑鼠右鍵按兩下接聽程式,選取 [屬性],輸入接聽程式的適當埠號碼,然後選取 [ 確定]。
方法 2:將接聽程式與現有的 SQL Server 故障轉移叢集實例產生關聯 (SQLFCI)
如果您要在 SQL Server 故障轉移叢集實例 (SQLFCI) 上裝載可用性群組,您可以在卸除再重新建立可用性群組時,將接聽程式叢集資源與 SQLFCI 叢集資源群組產生關聯。
啟動 [故障轉移叢集管理員],然後選取左窗格中的角色。
在列出角色的窗格中,選取原始可用性群組。
在 [資源] 索引標籤下方的中間窗格中,以滑鼠右鍵按兩下可用性群組資源,然後選取 [屬性]。
選取 [ 相依性] 索引卷標,刪除接聽程式的相依性,然後選取 [ 確定]。
在 [資源] 索引標籤下的底部中間窗格中,以滑鼠右鍵按兩下接聽程式,選取 [更多動作],然後選取 [指派給另一個角色]。
在 [ 將資源指派給角色 ] 對話框中,按兩下 [SQL Server FCI 實例],然後選取 [ 確定]。
在 [ 角色] 窗格中,選取 [SQLFCI] 群組。 在底部中間窗格的 [資源] 索引標籤下,您現在應該會看到新的接聽程序資源。
這可確保使用接聽程式的應用程式仍然可以使用它來連線到裝載生產資料庫的 SQL Server 實例,而不會中斷。 現在可以移除原始可用性群組並重新建立。 或者,資料庫和複本可以新增至新的可用性群組。
重新建立可用性群組之後,請將接聽程式重新指派回可用性群組角色。 然後設定新可用性群組資源與接聽程式之間的相依性,然後將埠重新指派給接聽程式:
- 啟動 [故障轉移叢集管理員],然後選取左窗格中的角色。
- 在列出角色的窗格中,單擊原始 SQLFCI 角色。
- 在底部中間窗格的 [資源] 索引標籤下,以滑鼠右鍵按兩下接聽程式,選取 [更多動作],然後選取 [指派給另一個角色]。
- 在對話框中,按兩下重新建立的可用性群組,然後選取 [ 確定]。
- 在 [ 角色] 窗格中,選取新的可用性群組。
- 在 [ 資源] 索引 標籤下,您應該會看到新的可用性群組和接聽程序資源。 以滑鼠右鍵按下新的可用性群組資源,然後選取 [ 屬性]。
- 選取 [ 相依性] 索引卷標,從下拉式方塊中選取接聽程式資源,然後選取 [ 確定]。
- 在 SQL Server Management Studio 中,使用 物件總管 連接到裝載新可用性群組主要複本的 SQL Server 實例。
- 選取 [ AlwaysOn 高可用性],按下新的可用性群組,然後選取 [ 可用性群組接聽程式]。 您應該會找到接聽程式。
- 以滑鼠右鍵按兩下接聽程式,選取 [屬性],輸入接聽程式的適當埠號碼,然後選取 [ 確定]。
方法 3:卸除可用性群組,然後使用相同的接聽程式名稱重新建立可用性群組和接聽程式
此方法會導致目前連線的應用程式發生小型中斷,因為可用性群組和接聽程式已卸除,然後重新建立:
卸除可用性群組。
注意
這也會卸除接聽程式。
在裝載生產資料庫的相同伺服器上,立即建立包含接聽程式定義的新空可用性群組。
例如,假設您的可用性群組接聽程式為 aglisten。 下列 Transact-SQL 語句會建立不含主要或輔助資料庫的可用性群組,但也會建立名為 aglisten 的接聽程式。 應用程式可以使用此接聽程式進行連線。
USE master GO CREATE AVAILABILITY GROUP ag FOR REPLICA ON 'sqlnode1' WITH ( ENDPOINT_URL = 'tcp://sqlnode1:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL ) LISTENER 'aglisten' ( WITH IP ((N'11.0.0.25', N'255.0.0.0')), PORT = 1433 ) GO
復原損毀的資料庫。 然後將它和次要復本新增回可用性群組。