練習 - 還原到某個時間點

已完成

在此練習中,您將了解如何使用時間點還原 (PITR) 從常見的錯誤中復原。 此程序在入口網站中或以程式設計方式很容易執行。 在此練習中,您將了解如何使用 Azure CLI 來執行這項操作。

設定:使用指令碼部署 Azure SQL Database

在右側終端中,您會看到 Azure Cloud Shell,這是使用瀏覽器來與 Azure 互動的方式。 在開始練習之前,您必須在該處執行指令碼以建立環境:包含 AdventureWorks 資料庫的 Azure SQL Database。 在指令碼中將會出現一些提示,要求提供密碼和本機 IP 位址。

這些指令碼大約需要 3 到 5 分鐘的時間才能完成。 請務必記下密碼、唯一識別碼和區域,因為之後不會再次顯示這些資訊。

  1. 若要取得所需要的 IP 位址,您必須從任何 VPN 服務中斷連線,並在本機 PowerShell 視窗 (而非瀏覽器) 中執行 (Invoke-WebRequest -Uri "https://ipinfo.io/ip").Content。 請記下產生的 IP 位址。

  2. 請在此頁面右側的 Azure Cloud Shell 中執行下列指令碼。 出現提示時,請輸入複雜密碼和公用 IP 位址。

    $adminSqlLogin = "cloudadmin"
    $password = Read-Host "Your username is 'cloudadmin'. Please enter a password for your Azure SQL Database server that meets the password requirements"
    # Prompt for local IP address
    $ipAddress = Read-Host "Disconnect your VPN, open PowerShell on your machine and run '(Invoke-WebRequest -Uri "https://ipinfo.io/ip").Content'. Please enter the value (include periods) next to 'Address': "
    # Get resource group and location and random string
    $resourceGroup = Get-AzResourceGroup | Where ResourceGroupName -like "<rgn>[sandbox resource group name]</rgn>"
    $resourceGroupName = "<rgn>[sandbox resource group name]</rgn>"
    $uniqueID = Get-Random -Minimum 100000 -Maximum 1000000
    $storageAccountName = "mslearnsa"+$uniqueID
    $location = $resourceGroup.Location
    # The logical server name has to be unique in the system
    $serverName = "aw-server$($uniqueID)"
    
  3. 在 Azure Cloud Shell 中執行下列指令碼,以輸出和儲存 (在文字檔或類似位置中) 會在整個課程模組中用到的資訊。 您可能需要在貼上程式碼之後選取 [輸入],因為最後一行預設不會執行。

    Write-Host "Please note your unique ID for future exercises in this module:"  
    Write-Host $uniqueID
    Write-Host "Your resource group name is:"
    Write-Host $resourceGroupName
    Write-Host "Your resources were deployed in the following region:"
    Write-Host $location
    Write-Host "Your server name is:"
    Write-Host $serverName
    

    重要

    請記得記下密碼、唯一識別碼和區域。 您在整個課程模組中都需要此資訊。

  4. 執行下列指令碼,以部署具有 AdventureWorks 範例的 Azure SQL Database 和邏輯伺服器。 此指令碼也會將您的 IP 位址新增為防火牆規則、啟用適用於雲端的 Microsoft Defender,並建立儲存體帳戶供接下來的單元使用。

    # The logical server name has to be unique in the system
    $serverName = "aw-server$($uniqueID)"
    # The sample database name
    $databaseName = "AdventureWorks"
    # The storage account name has to be unique in the system
    $storageAccountName = $("sql$($uniqueID)")
    # Create a new server with a system-wide unique server name
    $server = New-AzSqlServer -ResourceGroupName $resourceGroupName `
        -ServerName $serverName `
        -Location $location `
        -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force))
    # Create a server firewall rule that allows access from the specified IP range and all Azure services
    $serverFirewallRule = New-AzSqlServerFirewallRule `
        -ResourceGroupName $resourceGroupName `
        -ServerName $serverName `
        -FirewallRuleName "AllowedIPs" `
        -StartIpAddress $ipAddress -EndIpAddress $ipAddress
    $allowAzureIpsRule = New-AzSqlServerFirewallRule `
        -ResourceGroupName $resourceGroupName `
        -ServerName $serverName `
        -AllowAllAzureIPs
    # Create a database
    $database = New-AzSqlDatabase  -ResourceGroupName $resourceGroupName `
        -ServerName $serverName `
        -DatabaseName $databaseName `
        -SampleName "AdventureWorksLT" `
        -Edition "GeneralPurpose" -Vcore 2 -ComputeGeneration "Gen5"
    # Enable Azure Defender
    $azureDefender = Enable-AzSqlServerAdvancedDataSecurity `
        -ResourceGroupName $resourceGroupName `
        -ServerName $serverName
    # Create a storage account
    $storageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroupName `
        -AccountName $storageAccountName `
        -Location $location `
        -Type "Standard_LRS"
    
  5. 在本機電腦上開啟 SSMS,並向邏輯伺服器建立新連線。 針對伺服器名稱,請輸入 Azure SQL Database 邏輯伺服器的名稱。 如果您先前未儲存此名稱,您可能需要參考 Azure 入口網站來取得。 例如: aw-server\<unique ID>.database.windows.net

    1. 當您進入 Azure 入口網站之後,您可以在搜尋方塊中輸入 AdventureWorks 以尋找您的資料庫及其相關聯邏輯伺服器。

    2. 在 [驗證] 方塊中,輸入 [SQL Server 驗證]。 輸入對應的伺服器管理員 [登入] 和[密碼] (您在上一個練習中於部署期間提供的資訊)。

    3. 選取 [記住密碼] 方塊,然後選取 [連線]

    顯示如何在 SSMS 中連線到 SQL Database 的螢幕擷取畫面。

    注意

    根據本機設定 (例如 VPN) 而定,您的用戶端 IP 位址可能會與 Azure 入口網站在部署期間所使用的 IP 位址不同。 如果確實不同,您會看到一則訊息,表示「用戶端 IP 位址無法存取伺服器。 請登入 Azure 帳戶,並建立新的防火牆規則以啟用存取。」如果收到此訊息,請使用在沙箱中所用的帳戶來登入,並為用戶端 IP 位址新增防火牆規則。 您可以使用 SSMS 中的快顯精靈來完成這些步驟。

完成 PITR

在繼續之前,了解執行 PITR 的建議程序非常重要:

  1. 意外刪除一個資料表或資料庫。
  2. 判斷您需要返回的時間;這應該在錯誤發生之前。
  3. 請透過 PowerShell 或 Azure 入口網站完成 PITR 以回到這個時間點。 這會部署新的資料庫,並還原資料庫的複本。 例如:AdventureWorks-copy
  4. 確認新的資料庫 (例如 AdventureWorks-copy) 處於正確狀態 (意外發生之前的狀態)。
  5. 重新命名原始資料庫。 例如,將 AdventureWorks 重新命名為 AdventureWorks-old
  6. 以原始資料庫名稱重新命名新資料庫。 例如,將 AdventureWorks-copy 重新命名為 AdventureWorks
  7. 刪除原始資料庫。 例如:AdventureWorks-old

在此練習中,您將完成下列步驟。

模擬資料刪除

首先,請確認我們「意外」刪除的資料表確實存在且包含資料。 讓我們看看 SalesLT.OrderDetail 中的一些值。

  1. 移至 SSMS 並且檢查/更新您的連線。 選取 [檔案]>[連接物件總管],然後選取 [選項] 按鈕。

  2. 請確定您使用的連線會連線到邏輯伺服器,但是不會連線到特定資料庫。 (例如,使用 [預設]<>,如下列螢幕擷取畫面所示。)此外,請確認 [其他連線參數] 索引標籤中沒有包含任何文字。

    顯示預設連線的螢幕擷取畫面。

  3. 展開 [資料庫] 資料夾資料夾、以滑鼠右鍵按一下您的 AdventureWorks 資料庫,並選取 [新增查詢]。 輸入下列查詢並選取 [執行] 加以執行,然後檢閱結果:

    SELECT TOP 10 * from SalesLT.SalesOrderDetail
    

    顯示銷售訂單詳細資料資料表的螢幕擷取畫面。

  4. 透過卸除資料庫中的資料表來模擬資料遺失。

    在相同的查詢視窗中執行此查詢,然後在選取 [結果] 視窗中的 [訊息] 索引標籤,並記下完成時間:

    DROP TABLE SalesLT.SalesOrderDetail
    

    重要

    儲存完成時間。 稍後您將需要此資訊。 範例如下:Completion time: 2020-06-22T09:20:27.1859237-07:00

  5. 最後,在開始進行還原資料庫的步驟之前,請先在此頁面右側的 Azure Cloud Shell 中執行下列程式碼以設定環境:

    $resourceGroup = Get-AzResourceGroup | Where ResourceGroupName -like <rgn>[sandbox resource group name]</rgn>
    $server = Get-AzureRmSqlServer -ResourceGroupName $resourceGroup.ResourceGroupName
    $logical_server = $server.ServerName
    $resource_group = $resourceGroup.ResourceGroupName
    
    # Specify your default resource group and Azure SQL Database logical server
    az configure --defaults group=$resource_group sql-server=$logical_server
    
    # Confirm the defaults are set
    az configure --list-defaults
    

    所傳回 groupsql-server 參數應該會與 Microsoft Learn 資源群組和 Azure SQL Database 邏輯伺服器的名稱相同。

找出還原資料庫的目標時間點

第一個步驟是找出還原資料庫的目標時間點。 您必須知道在「不良」交易之前最後一個「良好」交易發生的時間。 您要將資料庫還原到不良交易之前,但是在最後一個良好交易之後。

  1. 判斷卸除時間的其中一種方式是,查看 DROP 陳述式的完成時間,您已在上一個步驟中記下此時間。

    替代方式是使用 Azure 入口網站中的稽核記錄。 在此練習中,您並未針對 Log Analytics 的設定稽核,但我們將探索如果設定稽核,您可以執行哪些動作。 您可以在 Azure 入口網站中移至您的 Azure SQL 資料庫。 在左窗格中的 [安全性] 下選取 [稽核],然後選取 [檢視稽核記錄]。 然後選取 [Log Analytics],您就會進入查詢編輯器,並且可以使用 Kusto 查詢語言 (KQL) 來查詢記錄。 SQL 專業人員可以使用此查詢語言輕鬆地查詢記錄。

    然後,您可以執行下列 KQL 查詢:

    search database_name_s == "AdventureWorks"
    | where Category == 'SQLSecurityAuditEvents' and statement_s like 'DROP'
    | project format_datetime(event_time_t, 'yyyy-MM-dd hh:mm:ss.fff'), ResourceGroup, server_instance_name_s, database_name_s,  statement_s, succeeded_s,client_ip_s, server_principal_name_s, application_name_s
    | sort by event_time_t desc
    

    結果應該類似下列結果,但是具有不同的日期和時間。

    顯示 Log Analytics 結果的螢幕擷取畫面。

    注意

    記錄可能需要 5 到 10 分鐘的時間才會出現在這裡,因此為了此練習的目的,我們加以省略。您將改為使用在上一個步驟中記下的完成時間。 (您必須將其轉換成 GMT。) 在真實世界的情況下,您不太可能會進入完成時間的視窗,因此,稽核有很大的幫助。

  2. 在此範例中,Log Analytics 的日期/時間是 2020-07-24 08:06:24.386,而 SSMS 則是2020-07-24T13:06:24.386-07:00。 所需的格式稍有不同。 使用下列範例來判斷正確的格式。 您可能也會想要減去 0.001 秒,以確保還原到錯誤發生「之前」的時間:

    • Log Analytics 格式:2020-07-24 08:06:24.386
    • SSMS 格式:2020-07-24T13:06:24.386-07:00
    • 必要格式:2020-07-24T20:06:24.385
  3. $before_error_time 設定為產生的結果值,以將此範例中的時間取代為您的時間:

    $before_error_time ="2020-07-24T20:06:24.385"
    

還原資料庫及確認遺漏的資料

在本節中您將使用 az cli db restore,將資料庫還原到資料表刪除之前的時間。

  1. 請在此視窗右側的終端機中執行下列指令碼:

    # Restore the database to a time before the database was deleted
    az sql db restore --dest-name "AdventureWorks-copy" --name "AdventureWorks" --time $before_error_time --verbose
    

    還原將需要 5 到 10 分鐘的時間。 當執行還原時,Azure 會在 Azure SQL Database 邏輯伺服器中部署新的 Azure SQL Database。 新的資料庫具有與原始資料庫相同的設定選項。 部署 Azure SQL 資料庫之後,Azure 會將資料庫還原至新的 Azure SQL 資料庫。

  2. 您可以藉由在 SSMS 中重新整理資料庫的檢視來檢查狀態。 以滑鼠右鍵按一下 [資料庫] 資料夾,並選取 [重新整理]。 部署資料庫之後,您會看到還原正在進行中:

    顯示資料庫正在 SSMS 中進行還原的螢幕擷取畫面。

    在您看到還原正在進行中之後,還原應該需要 2 到 3 分鐘以上的時間。 因為命令將會完成,所以您會在其完成時得知。 此外,您將不會在啟動重新整理時,於複製資料庫的旁邊繼續看到「(正在還原…)」。

    如果您注意到還原所花費的時間比稍早所述的時間還要久,這可能是因為您的 Microsoft Learn 環境所致。 針對單一訂用帳戶,每一次可處理/提交的還原要求數具有限制。 如果您想要在等待時深入了解限制和 PITR 的相關詳細資訊,請參閱從 Azure SQL Database 中的備份還原資料庫 (部分內容可能是機器或 AI 翻譯)。

  3. 您現在可以確認新的資料庫處於正確的狀態 (發生意外之前的狀態)。 在 SSMS 中的邏輯伺服器上按一下滑鼠右鍵,然後選取 [重新整理],將您的連線重新整理為連線至 Azure SQL Database 邏輯伺服器。

  4. 以滑鼠右鍵按一下新資料庫 (例如 AdventureWorks-copy),然後選取 [新增查詢]

    顯示如何建立查詢的螢幕擷取畫面。

  5. 使用此查詢以確認資料表存在:

    SELECT TOP 10 * from SalesLT.SalesOrderDetail
    

    您應該會得到類似下列螢幕擷取畫面中所示的結果。 此結果會確認您的資料庫已還原至您想要的位置。

    顯示銷售訂單詳細資料資料表的螢幕擷取畫面。

交換資料庫並進行清除

接下來,您可將原始資料庫重新命名為 AdventureWorks-old,以供在稍後重新命名新資料庫以使用原始資料庫的名稱。 只要您的應用程式使用重試邏輯,此變更就可以讓您不需要變更任何連接字串。

若資料庫在任何時間點顯示為無法使用 (例如若在 SSMS 中重新整理連線,即無法連線到資料庫),這可能是因為 DNS 表格發生更新。 因此,雖然資料庫實際上並非無法使用,但卻無法解決。 稍待一分鐘,您應該就能夠繼續一般活動。

  1. 使用此命令來變更資料庫名稱:

    az sql db rename --name "AdventureWorks" --new-name "AdventureWorks-old"
    
  2. 現在原始資料庫名稱已不再處於使用狀態,您可再次使用 Azure Cloud Shell 將複製資料庫重新命名為原始資料庫的名稱:

    az sql db rename --name "AdventureWorks-copy" --new-name "AdventureWorks"
    
  3. 您不需要舊的資料庫,因此您可以使用 az sql db delete 來將其刪除:

    az sql db delete --name "AdventureWorks-old" --yes
    Write-Host "Database deleted"
    
  4. 您可以使用下列命令,確認舊資料庫已不存在:

    az sql db list -o table
    

您現在已經了解如何在 Azure SQL Database 中使用 PITR。 您也可以在 Azure SQL 受控執行個體中針對資料庫使用 PITR,但是不能針對整個執行個體使用。 您可以使用幾乎相同的命令,不同之處在於您必須使用 az sql midb,而不是 az sql db