浅谈SQL Server中的事务日志(四)----在完整恢复模式下日志的角色
简介
生产环境下的数据是如果可以写在资产负债表上的话,我想这个资产所占的数额一定不会小。而墨菲定律(事情如果有变坏的可能,无论这种可能性有多小,它总会发生)仿佛是给DBA量身定做的。在上篇文章介绍的简单恢复模式下,从最近一次备份到当前的数据都会存在丢失的风险。而完整备份模式使得数据丢失的风险大大减少。本文主要介绍在完整备份模式下概念原理和日志所处的角色。
完整(Full)恢复模式
完整恢复模式通过将对数据库的任何修改记录到日志来给予数据最大程度的保护。在完整恢复模式下,日志的作用不仅仅是保证了数据库事务的ACID。并且还可以使数据恢复到在日志范围内的任何时间点。
在上一篇文章中说过,在简单恢复模式下,日志几乎是不用进行管理的。每一次CheckPoint都有可能截断日志,从而来回收不活动的VLF以便重复利用空间。因此在简单恢复模式下,日志的空间使用几乎可以不去考虑。与之相反,在完整恢复模式下,日志作为恢复数据的重要组成部分,日志的管理和对日志空间使用的管理则需要重视。
在完整恢复模式下,CheckPoint不会截断日志。只有对日志的备份才会将MinLSN向后推并截断日志。因此在一个业务量稍大的系统中,日志的增长速度将会变得很快。
因此日志备份的目的分为以下两个:
- 减少活动日志的大小
- 减少日志损坏的风险
通过从MSDN中摘自的下图可以看到:
在DB_1处做了完整备份,并且接下来两次分别做了两次日志备份(Log_1和Log_2),在Log_2备份完不久服务器由于数据所在磁盘损坏。这时如果日志文件完好,则可以通过备份尾部日志(Tail of log)后,从DB_1开始恢复,依次恢复Log_1,Log_2,尾部日志来将数据库恢复到灾难发生时的时间点。理论上可以使数据的损失为0。
从日志恢复数据的原理是Redo,也就是将日志中记载的事务再重做一遍。这个开销和从完整或差异备份中恢复相比,要大很多。因此尽可能的减少利用日志的恢复量。而使用完整或者差异备份来恢复更多的数据。
大容量日志(Bulk-logged)恢复模式
大容量恢复模式在很多地方和完整恢复模式相同。但由于在完整恢复模式下,对数据库的每一项操作都会记录在日志中。而对于某些大量数据的导入导出操作,无疑会在日志中留下大量记录。很多情况下,我们并不需要将这些信息记录在日志中。
而大容量日志恢复模式作为完整恢复模式的备选方案。微软推荐的最佳实践是在进行大量数据操作时(比如索引的创建和rebuilt,select into操作等),暂时由完整恢复模式切换到大容量恢复模式来节省日志。这个转换并不会破坏日志链。
本文不会深入探讨这个模式,仅仅是对这个概念做简单解释。假设我要插入一批数据,则完整恢复模式和大容量日志恢复模式在日志中所记录的信息如下:
由此可以看出,在日志中,大容量恢复模式将这类操作变为一个原子。
日志链(Log Chain)
连续的日志备份被称之为日志链。表示日志是连续的.这个概念可以用下图表示:
假设上面两个日志备份可以简单抽象成如上2个备份,则日志备份1的末尾LSN必须大于等于日志备份二的第一个LSN(通常情况下是第一个末尾LSN等于第二个日志备份的第一个LSN,但由于存在“只备份日志”选项只备份日志,并不截断日志,所以有可能重叠)。则这两个备份的日志链是连续的。
下图是一个生产环境下,在SSMS中查看日志链连续的例子:
可以看出,第一次完整备份后,备份多次事务日志,每一个事务日志的开始LSN都等于上一个事务日志的结束LSN。因此可以从第一次完整备份开始,恢复到最后一个日志备份期间的任何时间点。
完整的日志链以第一次完整备份或由简单恢复模式转为完整或大容量日志模式开始,到当前的时间点结束。
而从日志恢复数据要求从最近一次完整或差异备份到所恢复的时间点之间的日志链是连续的。
恢复次序
从备份恢复数据需要经历如下几步骤:
1.复制数据阶段:从完整备份和差异备份中将数据,索引页和日志复制到被恢复数据库文件。
2.Redo(roll forward)阶段:将记录在日志中的事务应用到从备份中复制过来的数据。使数据Roll Forward到指定的时间点.这个阶段完成后,数据库还处于不可使用阶段:
如图:
上面两部就是Restore
3.Undo(Roll Back)阶段:这也是传说中的Recovery,将任何未提交的事务回滚。这个阶段过后,数据库处于可用状态。任何后续备份将不能接着应用到当前数据库。
这个概念比如:
在连续两个日志链的日志备份,在第一个事务日志备份中定义的事务,在第二个事务日志备份中Commit.如果在第一个事务日志还原后使用了Recovery选项.也就是经历了Undo阶段。则事务1在Undo阶段会被回滚:
可见,日志备份1中的T1被回滚,在日志备份2中的Commit也就毫无意义。这也就是为什么经历过Undo阶段后不允许再恢复后续备份。因此,微软推荐的最佳实践是使用NoRecovery选项不进行Undo阶段。而在所有备份恢复后单独进行Undo阶段,这个操作可以通过还原日志尾部时,指定Recovery选项进行。
总结
本文简单介绍了在完整恢复模式下,日志的作用以及对数据恢复的一些概念。理解完整恢复模式的概念对于减少数据丢失的风险是无可替代的。
转载自:http://www.cnblogs.com/CareySon/archive/2012/02/23/2364572.html
浅谈SQL Server中的事务日志(四)----在完整恢复模式下日志的角色的更多相关文章
- 浅谈SQL Server中的事务日志(一)----事务日志的物理和逻辑构架
简介 SQL Server中的事务日志无疑是SQL Server中最重要的部分之一.因为SQL SERVER利用事务日志来确保持久性(Durability)和事务回滚(Rollback).从而还部分确 ...
- 浅谈SQL Server中的事务日志(三)----在简单恢复模式下日志的角色
简介 在简单恢复模式下,日志文件的作用仅仅是保证了SQL Server事务的ACID属性.并不承担具体的恢复数据的角色.正如”简单”这个词的字面意思一样,数据的备份和恢复仅仅是依赖于手动备份和恢复.在 ...
- 浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色
简介 每一个SQL Server的数据库都会按照其修改数据(insert,update,delete)的顺序将对应的日志记录到日志文件.SQL Server使用了Write-Ahead logging ...
- 浅谈SQL Server中的事务日志(五)----日志在高可用和灾难恢复中的作用
简介 日志的作用是保证持久性和数据一致性,通过日志可以实现数据的Undo与Redo,因此通过日志,SQL Server不仅仅可以实现灾难恢复,还可以通过日志的Redo来实现高可用性.本篇文章主要讲述日 ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- 浅谈SQL Server中的三种物理连接操作
简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...
- 浅谈SQL Server中的三种物理连接操作(HASH JOIN MERGE JOIN NESTED LOOP)
简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...
- 浅谈SQL Server中的三种物理连接操作(Nested Loop Join、Merge Join、Hash Join)
简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...
- 浅谈SQL Server中的快照
原文地址:http://www.cnblogs.com/CareySon/archive/2012/03/30/2424880.html 简介 数据库快照,正如其名称所示那样,是数据库在某一时间点的视 ...
随机推荐
- springmvc相关配置和用法
目录如下: 一.spring mvc 核心类与接口 二.spring mvc 核心流程图 三.spring mvc DispatcherServlet说明 四.spring mvc 父子上下文的说明 ...
- Docker镜像的导出和载入
https://www.cnblogs.com/lishidefengchen/p/10564765.html
- Rebranding(模拟+思维)
The name of one small but proud corporation consists of n lowercase English letters. The Corporation ...
- new Date("2018-01-01 11:11:11").valueOf() 在IE下会返回 NaN
原因是在ie下 new Date不能处理 小横线 这种时间格式,但是 替换成 斜线就可以正常获得毫秒数,像下面这样: new Date(('2018-01-01 11:11:11').replace( ...
- SPOJ - FAVDICE 简单期望
dp[0]=0; // rep(i,1,n) dp[i]=(double)(n-i)/n*dp[i-1]+1+(double)(i)/n*dp[i]; // (n-i)/n dp[i]= n-i / ...
- [转] SpringBoot RESTful 应用中的异常处理小结
[From] https://segmentfault.com/a/1190000006749441 SpringBoot RESTful 应用中的异常处理小结 永顺 2016年08月29日发布 赞 ...
- 使用dd命令写iso文件到u盘
1. 使用df -h查看挂载点 [seif@study ~]$ df -h 文件系统 容量 已用 可用 已用% 挂载点 udev 1.9G 0 1.9 ...
- PHP foreach ($arr as &$value)
foreach ($arr as &$value) 看到一个有意思的东西: <?php $arr = ['1', '2', '3', '4']; foreach ($arr as &am ...
- offset、client、scroll、screen的自己理解
body是DOM对象里的body子节点,即 <body> 标签: documentElement 是整个节点树的根节点root,即<html> 标签: window.scree ...
- ali代码风格
如下: <?xml version="1.0" encoding="UTF-8" standalone="no"?><pr ...