你们在工做中可能会遇到这样的场景: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和结尾日志复制代码