Sql-Server-2012

當數據庫超過一定大小時,數據庫鏡像設置不起作用,日誌不同步

  • September 11, 2018

我有一個大約 300gb 的 Microsoft 數據庫在生產中執行,我需要在兩個不同的伺服器上以鏡像配置傳輸和設置它。

這在我使用較小數據庫的測試中執行良好,但現在我在嘗試使用實際生產數據庫時遇到了以下問題。它大約有 3 次工作,其餘時間以錯誤結束。

嘗試在主伺服器上啟用鏡像時,會出現以下錯誤:“數據庫“myDatabase”的遠端副本尚未前滾到數據庫日誌的本地副本中包含的時間點。”

如果我然後嘗試對數據庫日誌進行新備份並在鏡像上還原:“消息 4305,級別 16,狀態 1,第 1 行此備份集中的日誌從 LSN 64612000000218000001 開始,它太新,無法應用於數據庫。可以恢復包含 LSN 64612000000217800001 的早期日誌備份。消息 3013,級別 16,狀態 1,第 1 行 RESTORE LOG 異常終止”

這就是我正在做的事情,它也非常耗時並且需要大量停機時間,所以如果有更簡單的方法我會很高興:

伺服器 A 是正在執行單個數據庫實例的目前生產伺服器。伺服器 B 是初始主數據庫伺服器 伺服器 C 是初始鏡像數據庫伺服器

我打破了伺服器 B 的鏡像並刪除了伺服器 B 和 C 上的數據庫。

ALTER DATABASE produktion SET PARTNER OFF

我從伺服器 A 進行備份並將其儲存在伺服器 B 上的共享文件夾中。

BACKUP DATABASE [myDatabase] TO  DISK = N'\\Server B\share\myDatabase.bak' WITH NOFORMAT, INIT,  NAME = N'myDatabase-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO

我從伺服器 B 上的備份恢復。

RESTORE DATABASE [myDatabase]    FROM DISK = '\\Server B\share\myDatabase.bak'    WITH 
MOVE 'mdflogicalfilename' TO    'D:\DEFAULT_2012_DATA\mdffile.mdf',
MOVE 'extralogicalfilename_extra' TO    'D:\DEFAULT_2012_DATA\extralogicalfilename_extra.mdf',
MOVE 'logfilename_log' TO    'E:\DEFAULT_2012_LOG\logfilename_log.ldf', 
NOUNLOAD, REPLACE, STATS =5;

我在伺服器 B 上進行了新備份(不確定這是否可以避免?)

ALTER DATABASE 'myDatabase' SET RECOVERY FULL;
BACKUP DATABASE 'myDatabase'
TO DISK = '\\Server C\share\myDatabase_full.bak' 
WITH INIT, FORMAT, STATS = 10;

BACKUP LOG 'myDatabase'
TO DISK = '\\Server C\share\myDatabase_log.bak'
WITH INIT, FORMAT, STATS = 10;

我從新備份恢復並使用 NORECOVERY 登錄伺服器 C

RESTORE DATABASE "myDatabase"    FROM DISK = '\\Server C\share\myDatabase.bak'    WITH 
MOVE 'mdflogicalfilename' TO    'D:\DEFAULT_2012_DATA\mdffile.mdf',
MOVE 'extralogicalfilename_extra' TO    'D:\DEFAULT_2012_DATA\extralogicalfilename_extra.mdf',
MOVE 'logfilename_log' TO    'E:\DEFAULT_2012_LOG\logfilename_log.ldf', 
NOUNLOAD, REPLACE, NORECOVERY;


RESTORE LOG "myDatabase"    FROM DISK = '\\Server C\share\myDatabase_log.bak'  WITH
NORECOVERY, STATS = 10;

在初始鏡像上啟用鏡像:

ALTER DATABASE myDatabase SET PARTNER = 'TCP://Server_B_FQN:myPort'

在初始主節點上啟用鏡像(這是失敗的地方):

ALTER DATABASE myDatabase SET PARTNER = 'TCP://Server_C_FQN:myPort'

整個過程大約需要 7-8 小時,我將每個步驟都創建為代理工作以開始下一個工作,但如果可以更快地完成某些事情,那將有很大幫助。

它大約有 3 次有效,其他時候我得到上述錯誤,我似乎無能為力,只能重新開始並希望它有效。

小型數據庫不會發生問題,因此問題可能是伺服器 C 上的還原需要很長時間,以至於伺服器 B 上的數據庫有時會創建新的日誌,然後這些日誌會不同步,這也可以解釋它在某些情況下起作用次,但在執行時間時沒有對數據庫進行任何更改。

有什麼方法可以恢復所有增量日誌並確保數據庫同步鏡像而不恢復數據庫的完整備份?

正如已經指出的那樣,可能會有第三方工具在您不知道的情況下進行備份。停止它(或至少對其進行控制)將無濟於事(顯然要注意,停止日誌備份可能會使 RPO/RTO 目標無效,並且進行臨時完整和日誌備份將使日誌鏈無效,並可能使 dr 恢復更多複雜或在此期間導致較大的數據失去)。

您提到您熱衷於減少所需的停機時間;我相信您有一些選擇可以幫助您。

我注意到您說的是 SQL Server 2012。備份壓縮在標準版以上版本中可用,啟用這將減少備份和恢復的 IO(以及因此時間),而 CPU 成本相對較低。我已經看到使用壓縮將備份減少了近一半(取決於數據庫中儲存的內容)。只需添加compression到您的with選項中。這可以與以下內容結合使用,以進一步減少中斷視窗。

選項 1 - 使用差異備份

與其在中斷時進行完整備份,不如進行完整備份(或者如果每天完成,則在昨晚進行)並在遷移到其他伺服器的當天將其恢復。然後,您可以在維護視窗中使用差異。由於差異備份僅包含自上次完整備份以來的更改,因此它比完整備份更小且速度更快。它也不依賴於日誌備份,因此只要您的完整備份良好,您就可以應用差異來使其同步。但請注意,必須在下一次完整備份之前獲取差異,以便知道計劃的視窗在每晚備份之前或暫停該數據庫的完整備份。

因此,您可以:

  • 在 A 上進行完整備份並將其還原到 B (NORECOVERY) 和 C (NORECOVERY),同時應用程序仍處於啟動狀態(並且日誌備份繼續進行)。
  • 等到您的中斷時間,停止日誌備份並進行差異備份
  • 更新您的連接字元串(或 CNAME)
  • 將差異恢復到 A(使用 RECOVERY)和 B(使用 NORECOVERY)
  • 在 B 和 C 之間啟動鏡像
  • 在 B 上啟動日誌備份

選項 2 - 鏡像

由於您目前不在鏡像配置中,您可以先在 A 和 B 之間創建鏡像;即使升級 SQL Server 版本,鏡像仍然可以以一種方式工作(從舊版本到新版本)。恢復和鏡像將在應用程序仍然線上的情況下完成,無需停機。

這可能看起來像:

  • 備份伺服器 A 並還原到 B (NORECOVERY)
  • 停止 A 上的日誌備份,獲取差異並還原到 B
  • 啟動鏡像(A –> B)
  • 重新啟動日誌備份
  • 當您的中斷視窗出現時,停止應用程序服務,更改 DNS CNAME(或連接字元串)
  • 故障轉移鏡像(從伺服器 Aalter database [mydb] with partner failover;
  • 再次啟動應用服務
  • 在 B 上啟動日誌備份計劃
  • 在 B 上備份完整數據庫
  • 恢復到 C (NORECOVERY)
  • 如果在備份和從 B 還原到 C 之間及時進行了日誌備份,則在 B 上進行差異化並還原到 C
  • 啟動鏡像

選項 3 - 日誌傳送

通過使用日誌傳送,您實際上可以同時播種 B 和 C。

該過程將類似於以下內容:

  • 進行完整備份並還原到 B 和 C (NORECOVERY)
  • 停止日誌備份(永久在第三方工具上)
  • 獲取並恢復 B 和 C 的差異 (NORECOVERY)
  • 使用 2 個輔助節點(B 和 C,NORECOVERY)啟動日誌傳送配置。這將創建日誌備份文件,因此可能需要向備份人員提及這一點,以便他們擷取位置,注意 SQL 代理服務需要對共享具有讀/寫權限才能工作。
  • 當停機時間中斷時,進行最終日誌備份並還原到輔助節點(在代理中找到的作業用於各個實例上的備份/還原作業)
  • 更改 CNAME(或連接字元串)
  • 使伺服器 B 數據庫退出還原狀態restore database [mydb] with recovery
  • 啟動鏡像
  • 在伺服器 B 上啟動日誌備份

引用自:https://dba.stackexchange.com/questions/158656