你們在工做中可能會遇到這樣的場景:sql
壁櫥裏的小王:哎呀!存放數據庫的磁盤滿了/爲何數據文件才100M,日誌文件已經暴漲到了200G/數據庫插入操做hang住了!!! 大佬,怎麼肥四?數據庫
隔壁老王:日誌太大,快作日誌收縮。bash
壁櫥裏的小王:老王,我作了啊,可是日誌沒有變小啊。服務器
隔壁老王:哦,那你作了日誌截斷嗎?工具
壁櫥裏的小王:。。。。啥意思sqlserver
若是你們也和壁櫥裏的小王同樣,一臉懵逼,截斷&收縮傻傻分不清楚,那麼,請往下看吧。性能
一 日誌fetch
二 日誌備份優化
三 日誌還原ui
四 經常使用工具
五 工做中苦逼的例子
1 日誌備份的意義:
2 日誌的本質 —— VLF
一個數據庫能夠有多個日誌文件,可是,邏輯上他們能夠當作一個。
SQL對日誌文件的管理,是將邏輯上的這一個ldf,分紅多個邏輯上的虛擬日誌文件(virtual log files,簡稱VLF)
日誌以整個VLF做爲單位進行增加和收縮,因此
——日誌文件是順序讀取,不像data page並行訪問,因此日誌文件分紅多個不會有性能上的提高。
3 VLF狀態
活動: 日誌活動部分(未commit的活動事務)——只要VLF中包含了活動日誌,就認 爲是活動VLF。
可恢復: 最老LSN以前的日誌 惟一做用就是保存以前記錄,以幫助回滾恢復到以前的某一狀態——還未截斷
可複用:最老LSN以前的日誌沒用了,就能夠複用了。——已經截斷(truncated)
未用:VLF還未被使用複製代碼
如何理解呢?請看下圖:
這是一個物理日誌文件,有8個VLF。使用順序看FSeqNo。
狀態status——2:VLF活動或可恢復 。 0:VLF可複用or徹底沒使用過
截斷(truncated)——只是將可恢復狀態的VLF轉換到可重用狀態
4 優化指北
指定適當的日誌文件大小和增加,是減小日誌碎片的關鍵。
一個日誌物理文件的VLF用完了,纔會使用下一個日誌文件。——適合的日誌大小和自我截斷,能夠只使用一個日誌文件
當全部日誌文件都用完(全部VLF都在用,status=2),增長日誌大小的時候,DB要遍歷全部日誌物理文件增長VLF(好比增長2m,每一個日誌物理文件都要增長2m)複製代碼
1 備份mode和恢復mode的區別
2 日誌截斷
截斷方法:
1 恢復Mode——簡單Mode【自動截斷】(事務一旦提交或回滾,該日誌這部分就能夠從新使用)
checkpoint會遍歷VLF,檢查是否有日誌能夠截斷。
若是有inactive的VLF時,CheckPoint都會將可截斷部分進行截斷,並將MinLSN向後推.
2 恢復Mode——完整Mode(CheckPoint不會截斷日誌,需手動截斷)
a.完整備份——sql認爲須要保存最老LSN以前的LSN,一旦再有活動事務就會增加VLF
——不會自動截斷——須要手動截斷
b.日誌備份,選擇日誌截斷複製代碼
1 還原的概念
日誌恢復數據要求從最近一次完整或差別備份到所恢復的時間點之間的日誌鏈是連續的
1複製數據:從完整備份和差別備份中將數據、索引頁和日誌複製到被恢復數據庫文件.
2Redo重作:日誌中事務在被恢復數據庫中重作一遍。——數據庫不可以使用
3Undo撤銷:Recovery,參考活動事務表,未提交事務回滾。——數據庫可用。不容許再恢復後續備份.複製代碼
2 數據庫寫操做總體流程
3 Check Point檢查點機制
1觸發:
* DPT||日誌 達到70%
* 週期寫入
2機制:
* DPT中LSN 小於等於 log外存的末尾LSN,符合條件的寫入外存E
3用處:
* 減小服務器恢復時間。檢查點這個LSN以前的日誌都落磁盤了。複製代碼
4 常見恢復數據庫作法
還原完整備份log
還原log
還原最後一個log,選擇Reconvery複製代碼
/*
* Author: jaki wang
* 全部數據庫: 全備,日誌備份,收縮日誌
*/
CREATE PROC [dbo].[SP_BACKUP_Shrinklog]
AS
BEGIN
DECLARE cur CURSOR FOR
SELECT NAME FROM Master..SysDatabases
WHERE name<>'master'
and name<>'model'
and name<>'msdb'
and name<>'tempdb'
DECLARE @tb SYSNAME --DB name
DECLARE @full VARCHAR(200) --DB BACKUP PATH
DECLARE @log VARCHAR(200) --DB BACKUP LOG PATH
OPEN cur
FETCH NEXT FROM cur INTO @tb
WHILE @@fetch_status=0
BEGIN
--backup mode: full
SELECT @full='c:\zlog\'+@tb+'_full' + REPLACE(CONVERT(nvarchar(20),GETDATE(),120),':','-') + '.bak'
BACKUP DATABASE @tb TO DISK=@full WITH INIT
--backup mode : log
SELECT @log='c:\zlog\'+@tb+'_log' + REPLACE(CONVERT(nvarchar(20),GETDATE(),120),':','-') + '.log'
BACKUP log @tb TO DISK=@log WITH INIT
---shrinklog for database
DBCC SHRINKDATABASE(@tb)
FETCH NEXT FROM cur INTO @tb
END
CLOSE cur
DEALLOCATE cur
END
GO
複製代碼
1 mdf數據文件錯刪
1日誌尾巴 備份 ——若是咱們還能作這種最後的備份的話
2文件夾有3個日誌備份文件:
全備
事務日誌備份
日誌尾巴備份
3數據庫還原:
徹底備份 norecovery
日誌備份 norecovery
tail備份 recovery複製代碼
2 sqlserver 實例崩潰——沒法經過t-sql備份結尾日誌
1咱們手上有的文件:數據庫ldf,備份的full bak和日誌備份log bak
2把文件copy到其餘擁有sql實例的機子上
3建立和原database同名的數據庫,設爲脫機
4刪除新建database的mdf文件
5用崩潰機子上的ldf替換新建database的ldf
6備份結尾日誌
7原有sql實例還原full,log和結尾日誌複製代碼