執行分頁還原

此主題與使用完整或大量記錄復原模式的 SQL Server 資料庫有關。分頁還原只支援讀取/寫入檔案群組。

分頁還原的目標是還原一個或多個受損頁面而毋需還原整個資料庫。一般而言,選定要還原的頁面會標示為「有疑問」,因為存取該頁面時發生問題。有疑問的頁面是在 msdb 資料庫的 suspect_pages 資料表中識別。

[!附註]

並非所有錯誤都需要還原。快取資料 (如次要索引) 可能會發生一個問題,只要重新計算資料,就可解決這個問題。例如,如果資料庫管理員卸除並重建次要索引,則儘管已修正損毀資料,也不會在 suspect_pages 資料表中指明為已修正。

多個資料庫頁面可以立即還原。記錄檔備份適用於包含正在復原之頁面的所有資料庫檔案。在檔案還原中,向前復原集會以單一記錄重做行程向前進行。

分頁還原主要是修復隔離的損毀頁面。還原和復原少數個別頁面可能比檔案還原更快,可以減少還原作業期間離線的資料量。不過,如果不只是要還原一個檔案中的幾個頁面,則還原整個檔案,通常更有效率。例如,如果在裝置上有很多頁面指出有暫止的裝置失敗,請考慮還原檔案,可能要還原至另一個位置,然後修復該裝置。

分頁還原實例

所有 SQL Server 2005 版本和之後的版本都支援在資料庫離線時還原頁面 (「離線分頁還原」)。在 SQL Server 2005 Enterprise Edition 和之後的版本中,如果資料庫在分頁還原期間處於線上,則資料庫會保持在線上。當資料庫在線上時還原和復原頁面稱為「線上分頁還原」。

這些分頁還原實例如下所示:

  • 離線分頁還原

    SQL Server 2005 Standard、SQL Server 2005 Express Edition 和 SQL Server 2005 Workgroup 以及更新版本只支援離線還原。如果資料庫已經離線,SQL Server 2005 Enterprise Edition 和更新版本就會使用離線還原。在離線分頁還原中,還原受損的分頁時資料庫是離線的。在還原順序結束後,資料庫會恢復上線。

    分頁還原若要成功,還原的頁面必須復原到與資料庫一致的狀態。必須套用未中斷的記錄備份鏈結至最後一個完整或差異還原,將包含該頁面的檔案群組向前帶到目前的記錄檔。

  • 線上分頁還原

    在 SQL Server 2005 Enterprise Edition 和之後的版本中,當條件允許時,分頁還原會自動在線上執行。在大部分情況下,損毀的頁面可以在資料庫保持上線時還原,包括正進行還原頁面的檔案群組在內。線上分頁還原對於因為硬體錯誤而發生損毀的頁面特別有用。

    偶而,損毀的頁面可能需要進行離線還原。例如,一些重要頁面損毀可能會讓資料庫無法啟動。在這些情況下,必須使用離線還原。

    [!附註]

    線上還原會嘗試更新中繼資料,但如果更新涉及重要頁面,該項更新可能會失敗。如果線上還原嘗試失敗,就必須離線執行還原。

線上分頁還原會利用 SQL Server 2005 和之後的版本中改良的頁面層級錯誤報告 (包括頁面總和檢查碼) 和追蹤。透過總和檢查碼機制或分次寫入方式偵測為損毀的頁面 (「損毀頁面」),可以在 RESTORE 陳述式中指定頁面加以還原。分頁還原是特別設計來還原少數幾個損毀頁面的。RESTORE 陳述式中指定的每個頁面都會以指定備份集的頁面加以取代。還原的分頁必須復原到與資料庫一致的狀態。只有明確指定的頁面才會還原。

分頁還原的限制

只能還原資料庫頁面。您無法使用分頁還原來還原下列項目:

  • 交易記錄

  • 配置頁面—全域配置對應 (Global Allocation Map,GAM) 頁面、共用全域配置對應 (Shared Global Allocation Map,SGAM) 頁面,以及頁面可用空間 (Page Free Space,PFS) 頁面。如需詳細資訊,請參閱<管理範圍配置與可用空間>。

  • 所有資料檔案的頁面 0 (檔案啟動頁面)

  • 頁面 1:9 (資料庫啟動頁面)

  • 全文檢索目錄

若無法還原個別頁面,您必須使用現有的完整資料庫備份,或是完整檔案或檔案群組備份。

[!附註]

若欲還原的頁面屬於特殊案例 (例如:中繼資料頁面),則線上分頁還原會失敗。在這些情況下,請嘗試離線分頁還原。

還原分頁的需求

分頁還原具有下列需求:

  • 資料庫必須使用完整或大量記錄復原模式。使用大量記錄模式時可能會有某些問題。如需詳細資訊,請參閱下節。

  • 無法還原位於唯讀檔案群組中的分頁。如果檔案群組中同時在進行分頁還原,則嘗試將檔案群組設定為唯讀時會失敗。

  • 還原順序必須以完整、檔案或檔案群組備份開始。

  • 分頁還原需要不中斷的記錄備份鏈結 (從舊記錄備份至最新的記錄備份),而且必須全部套用這些記錄備份,才能以最新的記錄檔來還原分頁。

  • 在每個還原步驟中,跟檔案還原順序相同,您可以加入多個頁面到向前復原集。

  • 資料庫備份和分頁還原不能同時執行。

大量記錄復原模式與分頁還原

對於使用大量記錄復原模式的資料庫,分頁還原具有下列其他條件:

  • 對於大量記錄資料而言,在檔案群組或分頁資料離線時進行備份會有問題,因為離線的資料並未記錄在記錄中。任何離線頁面都可以阻止備份記錄。在此情況下,請考慮使用 DBCC REPAIR,因為這可能會讓資料損失比還原最近備份還少。

  • 除非指定 WITH CONTINUE_AFTER_ERROR,否則大量記錄資料庫的記錄備份遇到損壞的分頁時會失敗。

  • 一般來說,分頁還原不適合用於大量記錄復原。

    執行分頁還原的最佳作法是將資料庫設定為完整復原模式,並嘗試記錄備份。如果記錄備份有效,您就可以進行分頁還原。如果記錄備份失敗,您會失去自從前次記錄備份之後的工作,或必須試著執行 DBCC,且必須搭配 REPAIR_ALLOW_DATA_LOSS 選項來執行。

基本分頁還原語法

若要在 RESTORE DATABASE 陳述式中指定分頁,您需要包含該頁面和頁面識別碼的檔案識別碼。所需語法如下:

RESTORE DATABASE database_name

   PAGE ='file:page [ ,...n ]' [ ,...n ]

   FROM <backup_device> [ ,...n ]

WITH NORECOVERY

如需有關 PAGE 選項之參數的詳細資訊,請參閱<RESTORE 引數 (Transact-SQL)>。如需有關 RESTORE DATABASE 語法的詳細資訊,請參閱<RESTORE (Transact-SQL)>。

分頁還原的程序

分頁還原的基本步驟如下:

  1. 取得要還原之已損壞分頁的頁面識別碼。總和檢查碼或分次寫入錯誤會傳回頁面識別碼,提供指定頁面所需的資訊。若要查閱已損壞頁面的頁面識別碼,請使用下列來源:

    頁面識別碼來源

    主題

    msdb..suspect_pages

    了解及管理 suspect_pages 資料表

    錯誤記錄檔

    檢視 SQL Server 錯誤記錄

    錯誤追蹤

    監視事件

    DBCC

    DBCC (Transact-SQL)

    WMI 提供者

    伺服器事件的 WMI 提供者概念

  2. 使用包含該頁面之完整資料庫、檔案或檔案群組備份,開始進行分頁還原。在 RESTORE DATABASE 陳述式中,使用 PAGE 子句來列出要還原之所有分頁的頁面識別碼。

    PAGE ='file:page [ ,...n ]'

  3. 套用最新差異

  4. 套用後續的記錄備份。

  5. 為包含還原頁面之最後一個 LSN 的資料庫建立新的記錄備份,亦即上次進行離線分頁還原的時點。最後一個 LSN (設定為順序中的第一個還原的一部分) 是重做目標 LSN。針對包含頁面的檔案進行線上向前復原可在重做目標 LSN 停止。若要知道檔案目前的重做目標 LSN,請參閱 sys.master_filesredo_target_lsn 資料行。如需詳細資訊,請參閱<sys.master_files (Transact-SQL)>。

  6. 還原新的記錄備份。套用此新的記錄備份後,就可完成分頁還原,頁面現在可以使用。

[!附註]

這個順序與檔案還原順序類似。事實上,分頁還原和檔案還原都可以做為相同順序的一部分來執行。

範例

下列範例會以 NORECOVERY 還原檔案 B 的四個損毀頁面。接著,兩個記錄備份會套用 NORECOVERY,後面接著以 RECOVERY 還原的結尾記錄備份。

重要事項重要事項

若受損的分頁中儲存重要資料庫中繼資料,則可能需要進行離線分頁還原順序。若要執行離線還原,必須備份交易記錄 WITH NORECOVERY。

下列範例是執行線上還原。在範例中,檔案 B 的檔案識別碼是 1,而損毀頁面的頁面識別碼是 57、202、916 和 1016。

RESTORE DATABASE <database> PAGE='1:57, 1:202, 1:916, 1:1016'
   FROM <file_backup_of_file_B> 
   WITH NORECOVERY;
RESTORE LOG <database> FROM <log_backup> 
   WITH NORECOVERY;
RESTORE LOG <database> FROM <log_backup> 
   WITH NORECOVERY; 
BACKUP LOG <database> TO <new_log_backup> 
RESTORE LOG <database> FROM <new_log_backup> WITH RECOVERY;
GO