[SQL SERVER][Maintain]管理交易記錄檔(1)
交易記錄檔暴增問題是我常常看到的問題,
大多數情況交易記錄檔大小往往都是資料庫大小數十倍以上,
如果DBA放任不管理交易記錄檔的話,
過大的交易記錄檔會影響DB Mirroring、Log Shipping、CDC、Replication、備份效能...等,
嚴重將導致資料庫成為唯讀狀態(硬碟空間被吃爆,SQL Server拋出9002錯誤),
所以管理交易記錄檔可說是相當重要。
論壇網友詢問在做Tables大量寫入,更新,計算,刪除時希望log不會變很大?
因為我大多數的case都不允許我更改資料庫復原模式,
所以我這裡簡單測試在完整復原模式下的方法。
建立交易記錄檔初始大小=60MB 成長量=10MB,RecoveryMode=Full
建立來源資料表(新增40萬筆後交易記錄檔使用量)
SELECT instance_name AS DatabaseName,
[Data File(s) Size (KB)],
[LOG File(s) Size (KB)],
[Log File(s) Used Size (KB)],
[Percent Log Used]
FROM
(
SELECT *
FROM sys.dm_os_performance_counters
WHERE counter_name IN
(
'Data File(s) Size (KB)',
'Log File(s) Size (KB)',
'Log File(s) Used Size (KB)',
'Percent Log Used'
)
AND instance_name != '_Total'
) AS Src
PIVOT
(
MAX(cntr_value)
FOR counter_name IN
(
[Data File(s) Size (KB)],
[LOG File(s) Size (KB)],
[Log File(s) Used Size (KB)],
[Percent Log Used]
)
) AS pvt
WHERE instance_name='demo'
建立來源資料表並匯入資料,交易記錄檔使用16999(KB)27%。
接下來模擬網友資料操作過程
Create
CREATE TABLE [dbo].[MyLOG1](
[LogId] [int] identity(1,1) NOT NULL,
agentname varchar(30) not null,
[LogDate] [datetime] NOT NULL,
constraint PK_MyLOG1 primary key(LogId)
) ON [PRIMARY]
Add Column
ALTER table dbo.MyLOG1 add new1 char(1) null
Move Data(移動300000筆)
INSERT INTO MyLOG1 (agentname,LogDate)
SELECT agentname,LogDate FROM sourceLog
where [LogId]>0 AND [LogId]<=300000
總共使用36191 KB,最後交易記錄檔大小53190KB。
由於邏輯交易記錄檔結尾已達實體記錄檔結尾,
且沒有執行交易記錄檔備份(沒有截斷並標示之前空間重用),
所以發生實體交易記錄檔自動擴充行為(新增VLF)。
註:
VLF數量沒有固定。
VLF大小沒有固定。
VLF會從實體記錄檔最前面開始依順序寫入紀錄。
接下來執行備份資料庫和交易記錄檔後,看看備份檔案大小。
避免長時間交易(減少資料量)和uncommitted 交易
上面我們知道資料操作會產生大量的交易記錄,
所以下面針對資料操作我將使用迴圈來處理,
將每一批次資料量縮小(藉以縮短交易時間),
並和大交易資料量所產生的交易記錄大小做個比較,
照理說短時間交易會產生較小的交易記錄量。
刪除資料庫並重新建立資料庫和來源資料表,
這次針對資料操作改成迴圈處理大資料量(同樣30萬筆)。
DECLARE @batchcount int,@startcount int
set @batchcount=2000
set @startcount=0
BEGIN try
WHILE(@batchcount<=300000)
begin
INSERT INTO MyLOG2 (agentname,LogDate)
SELECT agentname,LogDate FROM SourceLOG
where [LogId]>@startcount AND [LogId]<=@batchcount
set @startcount= @batchcount
set @batchcount=@batchcount+2000
end
end try
begin catch
print error_message();
end catch
總共多了20780 KB,最後交易記錄檔大小37788KB。
和第一次大交易資料量整整少了快20MB的交易記錄檔大小,
拆解小交易資料量果然使用較少交易記錄量,
同時也沒有發生交易記錄檔擴充處理,
這是因為SQL Server不需要額外過多的交易記錄檔空間來存放rollback操作記錄,
這是要確保可以正常完成rollback作業,
所以縮短交易時間可以達到減少交易記錄檔大小也是很合理的。
接下來執行備份資料庫和交易記錄檔後,並和之前備份檔案比較一下。
善用Partition Table
針對資料新增、刪除作業是否還有其他方法來減少交易記錄檔大小呢?
答案當然是有的,你可以參考我之前的Partition Table來處理,
因為switch partition方法只有紀錄metadata(最小記錄)。
[SQL SERVER][Performance]善用Partition Table#2測試
結論
交易記錄檔的暴增,都是因為長時間(龐大)交易活動所造成,
例如龐大的資料新增、刪除、更新或索引重建維護作業,
如果這些作業可以在簡單或大量紀錄復原模式下操作的話,
基本上可以減少交易記錄檔成長的大小(因為這兩種模式只記錄最小操作過程記錄),
但我遇到大多數正示環境資料庫都不太允許更改復原模式(會有資料遺失風險-SLAs and OLAs),
所以往往這些龐大作業幾乎都得在完整復原模式下執行,
這時交易記錄檔初始大小、成長大小和交易記錄檔備份頻率規畫就相當重要了,
當然還是要避免長時間交易,因為這不管資料庫是什麼樣的復原模式。
注意:
大多數人認為執行資料庫完整備份就會自動截斷交易記錄檔並保護data file and log file內容,
但事實上並不會截斷交易記錄檔,而且只有保護data file 內容並不保護log file 內容,
只要沒有執行備份交易記錄檔,交易記錄檔空間不會被截斷並標示重用,
且交易記錄檔將持續成長(直到硬碟空間滿),這裡特別提醒一下。
參考