共用方式為


Hyper-V 複寫在系統關機時暫停

本文有助於解決當主伺服器或複本伺服器關閉時,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:使用腳本自動重新啟動複寫

您也可以在工作排程器中設定複 寫自動重新啟動腳本 ,以在系統啟動時自動重新啟動複寫。

腳本會自動重新啟動在系統重新啟動或關機時暫停的複寫,如果複寫處於暫停狀態,則會自動繼續複寫。

在主伺服器和復本伺服器上遵循下列步驟:

  1. 複製復寫自動重新啟動腳本,並將它儲存在任何資料夾(例如 C:\Scripts),檔名 restartReplication.ps1

  2. 啟動 PowerShell 並執行下列 Cmdlet:

    PS > Set-ExecutionPolicy RemoteSigned
    

    注意

    • 您不需要在已經執行過 Cmdlet 的系統上再執行。
    • PowerShell 預設無法在從未執行 PowerShell 的系統上啟動。
  3. 按 Windows 標誌鍵 + X 以顯示畫面左下方的功能表,然後選取 [ 計算機管理]。

  4. 展開 左窗格中的任務排程器 。 選取並按住 [或以滑鼠右鍵按兩下] 工作排程器連結庫,然後選取 [ 建立工作]。 工作建立視窗將被顯示。

  5. 在 [ 一般 ] 索引標籤上設定下列選項:

    • 名稱:指定工作名稱(例如 Hyper-V 複本自動回復工作
    • 執行工作時,請使用下列使用者帳戶:指定具有系統管理員許可權的用戶帳戶(例如 <功能變數名稱>\系統管理員
    • 只有在使用者登入時才執行:取消核取選項
    • 不論使用者是否登入皆執行:勾選此選項
    • 以最高許可權執行:檢查選項
  6. 選取觸發條件標籤,然後選取新增

  7. 設定下列選項,然後選取 [ 確定]:

    • 開始工作:選取 [啟動時]
    • 進階設定>已啟用:檢查選項

    注意

    其他選項未被勾選。

  8. 選取 [動作] 標籤,然後選取 [新增]

  9. 設定下列選項,然後選取 [ 確定]:

    • 動作:選取 [啟動程式]
    • 程式/文稿:類型 powershell.exe
    • 新增自變數 (選擇性):指定自動重新啟動腳本的完整路徑 (例如 C:\Scripts\restartReplication.ps1
    • 從(選填)開始:將值留空
  10. 在 [條件] 和 [設定] 索引標籤上保留預設設定,然後選取 [確定] 以完成設定。

當驗證提示時,請輸入系統管理員密碼。

測試腳本的作業狀態

完成文稿的設定之後,您可以遵循下列步驟來測試主伺服器上的腳本作業狀態。

  1. 從主伺服器的 Hyper-V 管理員選取複寫所設定的虛擬機。 選取並按住(或按滑鼠右鍵)它,然後選取複製>暫停複製以刻意暫停操作。

  2. 在 Hyper-V 管理員中選取暫停的虛擬機器,然後選取畫面底部的 [複寫] 索引標籤。 請確定複寫狀態暫停

  3. 重新啟動主伺服器。 如果無法重新啟動,請在主伺服器上啟動工作排程器。 選取並按住(或按滑鼠右鍵)上述建立的任務,然後選取 執行

  4. 腳本會在系統啟動時執行,或執行手動工作。 若要檢查複寫是否自動重新啟動,請在主伺服器上的 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
    }
}