本文有助於解決當主伺服器或複本伺服器關閉時,Hyper-V 複寫暫停的問題。
當主伺服器或複本伺服器關閉時,Hyper-V 複寫會暫停。 此外,Hyper-V 虛擬機管理服務 (VMMS) 會記錄事件標識碼為 32086 和 32022 的一系列事件記錄檔。
事件標識碼 32086
Log Name: Microsoft-Windows-Hyper-V-VMMS/Admin Source: Hyper-V-VMMS Event ID: 32086 Level: Error Description: Hyper-V suspended replication for virtual machine <VM Name> due to a non-recoverable failure. Resume replication after correcting the failure. (Virtual machine ID <VM GUID>)
事件標識碼 32022
Log Name: Microsoft-Windows-Hyper-V-VMMS/Admin Source: Hyper-V-VMMS Event ID: 32022 Level: Error Description: Hyper-V could not replicate changes for virtual machine <VM Name>: The operation has been canceled (0x80004004). (Virtual Machine ID <VM GUID>)
注意
描述也可能包含「作業已中斷(0x80004004)」訊息。
此問題發生在 Windows Server 2012 Standard、Windows Server 2012 Datacenter 和 Windows Server 2012 R2 Standard 中。 此問題已在 Windows Server 2016 KB4088889中修正。
原因:Hyper-V VMMS 停止發出新進程
之所以發生此問題,是因為 Hyper-V VMMS 停止發出新進程。 當主要伺服器和複本伺服器關閉時,Hyper-V VMMS 會停止發出新的進程(工作)。 如果 Hyper-V 複本伺服器的數據在此時具有差異地送達或進行傳輸,則傳輸或接收過程無法進行,且復寫可能會暫停。
因應措施 1:手動重新啟動複寫
您可以在 Hyper-V 管理員中選取並按住(或右鍵點擊)虛擬機器,然後選取 複寫>繼續複寫 來手動重新啟動複寫。
因應措施 2:使用腳本自動重新啟動複寫
您也可以在工作排程器中設定複 寫自動重新啟動腳本 ,以在系統啟動時自動重新啟動複寫。
腳本會自動重新啟動在系統重新啟動或關機時暫停的複寫,如果複寫處於暫停狀態,則會自動繼續複寫。
在主伺服器和復本伺服器上遵循下列步驟:
複製復寫自動重新啟動腳本,並將它儲存在任何資料夾(例如 C:\Scripts),檔名 restartReplication.ps1。
啟動 PowerShell 並執行下列 Cmdlet:
PS > Set-ExecutionPolicy RemoteSigned
注意
- 您不需要在已經執行過 Cmdlet 的系統上再執行。
- PowerShell 預設無法在從未執行 PowerShell 的系統上啟動。
按 Windows 標誌鍵 + X 以顯示畫面左下方的功能表,然後選取 [ 計算機管理]。
展開 左窗格中的任務排程器 。 選取並按住 [或以滑鼠右鍵按兩下] 工作排程器連結庫,然後選取 [ 建立工作]。 工作建立視窗將被顯示。
在 [ 一般 ] 索引標籤上設定下列選項:
- 名稱:指定工作名稱(例如 Hyper-V 複本自動回復工作)
- 執行工作時,請使用下列使用者帳戶:指定具有系統管理員許可權的用戶帳戶(例如 <功能變數名稱>\系統管理員)
- 只有在使用者登入時才執行:取消核取選項
- 不論使用者是否登入皆執行:勾選此選項
- 以最高許可權執行:檢查選項
選取觸發條件標籤,然後選取新增。
設定下列選項,然後選取 [ 確定]:
- 開始工作:選取 [啟動時]
- 進階設定>已啟用:檢查選項
注意
其他選項未被勾選。
選取 [動作] 標籤,然後選取 [新增]。
設定下列選項,然後選取 [ 確定]:
- 動作:選取 [啟動程式]
- 程式/文稿:類型 powershell.exe
- 新增自變數 (選擇性):指定自動重新啟動腳本的完整路徑 (例如 C:\Scripts\restartReplication.ps1)
- 從(選填)開始:將值留空
在 [條件] 和 [設定] 索引標籤上保留預設設定,然後選取 [確定] 以完成設定。
當驗證提示時,請輸入系統管理員密碼。
測試腳本的作業狀態
完成文稿的設定之後,您可以遵循下列步驟來測試主伺服器上的腳本作業狀態。
從主伺服器的 Hyper-V 管理員選取複寫所設定的虛擬機。 選取並按住(或按滑鼠右鍵)它,然後選取複製>暫停複製以刻意暫停操作。
在 Hyper-V 管理員中選取暫停的虛擬機器,然後選取畫面底部的 [複寫] 索引標籤。 請確定複寫狀態為暫停。
重新啟動主伺服器。 如果無法重新啟動,請在主伺服器上啟動工作排程器。 選取並按住(或按滑鼠右鍵)上述建立的任務,然後選取 執行。
腳本會在系統啟動時執行,或執行手動工作。 若要檢查複寫是否自動重新啟動,請在主伺服器上的 Hyper-V 管理員中選取暫停的虛擬機,然後選擇位於畫面底部的 [複寫] 索引標籤。 如果 複製狀態 為 複製已啟用,則複製已正常恢復。
您也可以檢查系統事件記錄檔,以確認腳本的作業狀態。
啟動腳本的事件
Log Name: System Source: Hyper-V Replica script Event ID: 0 Level: Information Description: Starting script to restart replication.
恢復複製的事件
Log Name: System Source: Hyper-V Replica script Event ID: 4 Level: Information Description: Replication for <VM Name> on <Primary Server Name> was in suspended and resumed successfully.
如果發生重新啟動失敗之類的錯誤,錯誤內容會記錄在系統事件記錄檔中,並具有名為 「Hyper-V 複本腳本」 的事件來源。
複寫自動重新啟動腳本
以下是複製自動重啟腳本:
$EventSource = "Hyper-V Replica script" ### Event source name recorded in system log.
$StartUpTimeout = 60 ### Startup timeout value for replication service in second.
If ([System.Diagnostics.EventLog]::SourceExists($EventSource) -eq $false)
{
New-EventLog -LogName System -Source $EventSource
}
Write-EventLog -LogName System -Source $EventSource -EntryType Information -EventID 0 -Message "Starting script to restart replication."
### Wait until VMMS starts up.
(Get-Service "vmms").WaitForStatus("Running") ### No timeout.
### Wait until replication service in VMMS gets active.
$Count = 0
While((Get-VMReplication).count -eq 0)
{
Start-Sleep -s 1
$Count++
If ($Count -eq $StartUpTimeout)
{
Write-EventLog -LogName System -Source $EventSource -EntryType Error -EventID 1 -Message "VMMS did not complete initialization after VMMS service started up. Exiting..."
Exit(1)
}
}
$Message = "Replication service in VMMS was started successfully. It took " + $Count + " seconds after VMMS started."
Write-EventLog -LogName System -Source $EventSource -EntryType Information -EventID 2 -Message $Message
###
### MAIN
###
$LocalVMs = Get-VMReplication ### Get local VMs with replication enabled.
Foreach($LocalVM in $LocalVMs)
{
$PrimaryServer = $LocalVM.PrimaryServer
$VMName = $LocalVM.Name
### Get-VMReplication will access remote primary server if this VM is RecoveryVM.
$VM = Get-VMReplication -ComputerName $PrimaryServer | Where-Object { $_.Name -eq $VMName}
If ($VM -eq $null -or $VM.count -eq 0)
{
$Message = "Get-VMReplication has failed." + $Error[0].Exception + "(VM: " + $VMName + " Server: " + $PrimaryServer + ")"
Write-EventLog -LogName System -Source $EventSource -EntryType Error -EventID 3 -Message $Message
Exit(1)
}
### If the VM is normal, move to next VM.
If ($VM.State -ne "Suspended" -and $VM.State -ne "Error") { continue }
### Resuming replication here.
$Err = Resume-VMReplication -VMName $VMName -ComputerName $PrimaryServer 2>&1
### Wait status update for 1 sec.
Start-Sleep -s 1
### Checking the replication status after resuming the replication
$CurrentVM = Get-VMReplication -ComputerName $PrimaryServer | Where-Object { $_.Name -eq $VMName}
### If the replication state is still in suspended or error, it logs to event service.
If ($CurrentVM.State -eq "Suspended" -or $VM.State -eq "Error")
{
$Message = "Failed to resume replication for " + $VMName + " on " + $PrimaryServer + ". Please check replication status manually." + $Err.Exception
Write-EventLog -LogName System -Source $EventSource -EntryType Error -EventID 3 -Message $Message
}
Else
{
$Message = "Replication for " + $VMName + " on " + $PrimaryServer + " was in suspended and resumed successfully."
Write-EventLog -LogName System -Source $EventSource -EntryType Information -EventID 4 -Message $Message
}
}