在復原模式full or bulk-logged 的使用下,當SQL資料庫Transaction log增加速度變快時,我們會增加執行交易紀錄備份(Transaction log backup)的頻率來加速截斷交易紀錄,已經使用的交易紀錄空間(VLFs)就可以被標示inactive而被重複使用。
不過在AlwaysOn環境遇到一個特別的經驗,即使作了交易紀錄備份也沒辦法截斷交易紀錄,也因此讓Transaction log成長了幾次,來實驗看看當其中一台次要複本資料出現未進行同步處理狀態(NOT SYNCHRONIZING)的後續症狀。
測試的AlwaysOn環境有3台DB,DB1是主要複本,DB2是同步(synchronous)的次要複本,DB3則是非同步(Asynchronous)的次要複本。
查詢延遲截斷交易紀錄原因
如果發現有延遲截斷交易紀錄的現象,可以查詢sys.databases catalog view,從欄位log_reuse_wait_desc找到可能延遲的原因,我們這次出現的是9:AVAILABILITY_REPLICA
看起來是次要複本資料庫還在等待處理交易紀錄
*log_reuse_wait_desc: 交易記錄空間的重複利用正等待進行最後一個檢查點的下列其中一個作業
我們來實驗模擬這次遇到的狀況,時光重現的順序:
- 執行前,觀察DB1、DB2及DB3的log使用狀況
- 製造複本資料庫不再接收同步的現象
- 執行交易紀錄備份(Transaction log Backup),並且觀察DB1、DB2及DB3的log使用狀況是否降低
- 恢復DB3複本資料庫開始同步
- 再執行交易紀錄備份(Transaction log Backup),觀察DB1、DB2及DB3的log使用狀況是否降低
執行前,觀察DB1、DB2及DB3的log使用狀況
分別連到DB1、DB2及DB3的Instance執行
SELECT @@servername
DBCC SQLPERF(logspace)
執行結果:
製造複本資料庫不再接收同步的現象
我們選非同步(Asynchronous)的複本DB3,手動用SQL指令暫停同步
ALTER database AGdb set hadr suspend
出現了 "未進行同步處理"
執行交易紀錄備份(Transaction log Backup)
BACKUP LOG [AGdb] TO DISK = N'E:\SQL\AGDb_2017102801.trn'
WITH NOFORMAT, NOINIT, NAME = N'AGDB資料庫 備份', SKIP, NOREWIND, NOUNLOAD, STATS = 10
GO
再查詢一次log使用狀況,發現沒有截斷交易紀錄,而且三台DB都是,他們果然是一國的!
SELECT @@servername
DBCC SQLPERF(logspace)
沒有降下來,還是46%,有種交通阻塞的悶。
恢復DB3複本資料庫開始同步
ALTER database AGdb set hadr RESUME
再執行交易紀錄備份(Transaction log Backup)
BACKUP LOG [AGdb] TO DISK = N'E:\SQL\AGDb_2017102802.trn'
WITH NOFORMAT, NOINIT, NAME = N'AGDB資料庫 備份', SKIP, NOREWIND, NOUNLOAD, STATS = 10
GO
交易記錄檔的使用情形,由 46% 降為 17% .
小結:
如果次要複本伺服器一時之間回不來,只好當斷則斷,捨不下永遠無得,勘不破正是迷障.
ALTER AVAILABILITY GROUP [AG]
REMOVE REPLICA ON N'DB3';
增加Transaction log備份頻率: 截斷交易紀錄(減少過多VLFs) + 更好的RPO(Recovery Point Objective復原點目標)
docs says
建議您時常進行記錄備份,以將工作損失風險降至最低,同時也讓記錄能夠截斷。
參考
Factors that can delay log truncation
ALTER DATABASE (TRANSACT-SQL) SET HADR
redo thread and a switch-role thread DeadLock導致的未進行同步處理