为什么完整备份不能截断事务日志

导言


完整备份不能截断事务日志,这是所有SQL Server
DBA的一个常识,

为此,当数据库处于完整恢复模式时(非特别说明,下文所提到都是完整恢复模式下的数据库),DBA们必须频繁地使用事务日志备份的方式来防止日志文件变得过大。

这几乎成为了DBA们的一个定理,但,作为一个DBA,你证明过这个定理吗?你知道为什么完整备份不能截断事务日志吗?

一个错误的”常识“


将一个完整备份还原到新数据库时,新数据库无论是mdf还是ldf,其大小都跟原始数据库一模一样,

以至于我们认为完整备份包括了mdf中所有数据和ldf中的所有事务日志。这几乎成为了一些DBA的”常识“。

正是如此,我们有”理由“认为:数据库在完整备份后,ldf中的事务日志应该被截断,没必要再保存一个副本。

让“常识”站不住脚


按照这个”常识“,既然完整备份中包含了原始数据库中所有的事务日志,那通过完整备份还原得到的新数据库应该也含有同样的事务日志。下面我们通过一个小实验来验证实际情况是否是这样。

验证思路:


--首先新建一个数据库和一张表,并将数据库设置完整恢复模式下

CREATE DATABASE test;
USE Test;
CREATE TABLE t1(col1 INT,col2
VARCHAR(25));
 ALTER DATABASE Test SET RECOVERY FULL;


--在表中插入5条数据


INSERT INTO t1 VALUES(1,‘chen1‘);
INSERT INTO t1 VALUES(2,‘chen2‘);

INSERT INTO t1 VALUES(3,‘chen3‘);
INSERT INTO t1 VALUES(4,‘chen4‘);

INSERT INTO t1 VALUES(5,‘chen5‘);



--完整备份数据库


BACKUP DATABASE
Test TO DISK=‘d:\temp\oldtest.bak‘
--还原到新数据库


RESTORE DATABASE
test_new FROM DISK=‘d:\temp\oldtest.bak‘
WITH MOVE ‘test‘ TO ‘d:\temp\test.mdf‘, MOVE
‘test_log‘ TO ‘d:\temp\test_log.ldf‘
 --对比新老数据库LDF中的事务日志大小 DBCC SQLPERF(LOGSPACE)
--结果:LDF文件大小相同

  --对比新老数据库LDF中的事务日志内容(通过ApexSQL
Log软件分析新老数据库的LDF文件)
--结果:原数据库和新数据库的事务日志不相同

结论1:

通过完整备份文件还原得到的数据库,尽管其LDF的大小与原数据库相同,但两者所包含的事务日志并不完全相同,如上例所述,原数据库test包含5条insert的事务日志,而新数据库test_new没有这些事务日志。如果完整备份截断了事务日志,则无论是原数据库的LDF文件还是完整备份文件,都将不包含事务日志,这无异于将数据库置于简单恢复模式下,显然不符合我们将数据库设置成完整恢复模式的初衷。

完整备份的那些事


通过上述实例我们已经有了足够的理由推翻那个错误的“常识”,但,这个例子似乎并不完美,因为它又将我们导向了另一个错误的极端——完整备份不包括任何事务日志。

真是这样的吗?

本质是是现象的根源,只有真正了解了数据库完整备份期间发生的那些事,我们才能揭开层层迷雾。

归纳起来,数据库的完整备份主要包括如下几个步骤:

    1. 执行Checkpoint,并标记此时数据库中事务日志的LSN

    2. 开始读取、拷贝data files中的数据

    3. 结束data
      files的读取和拷贝,并记录此时最后一个活动日志的起始LSN

    4. 读取并拷贝必需的日志文件

摘自:http://technet.microsoft.com/en-us/magazine/2009.07.sqlbackup.aspx#id0980008

备注:读者在查看上述日志时,请先开启3004、3605、3502这三个跟踪标记。

DBCC
TRACEON(3004,3605,3502,-1)

至此,我们已经明白了,在完整备份文件里,它虽然没有包含所有的事务日志,但在完整备份期间,拷贝日志的动作一直存在,按照SQL
Server的说法,完整备份选择性的保存了数据库必需的事务日志。

为什么要选择性的保存这些必需事务日志呢?什么是“必需的事务日志”?而我的样例中新数据库为何没有任何事务日志?

在回答这些问题前,我们先看一下MSDN对完整备份文件的一个描述:

Full
database backups represent the database at the time the backup
finished.

也就是说,完整备份文件能够呈现数据库在备份完成时间点的所有数据,那么,这些足够多的事务日志的目的肯定是为了将数据库还原到备份完成时的时间点。

有了这个概念,我们来看一个完整备份的场景,下图绿色的数字代表完整备份的每个步骤:

  1. 执行事务A

  2. 执行完整备份和checkpoint,开始读取和拷贝数据文件

  3. 备份进程读取数据页X

  4. 执行事务B,改变数据页X的数据

  5. 结束事务B

  6. 结束对数据文件的读取和拷贝

数据库的完整备份从时间点2持续到时间点7。

对于页面
X,在时间点3做了备份后,在时间点5被事务B做了修改,因此,此时备份文件中页面X的数据已经过期了、不准确,而备份进程不会回过头来重新读取页面X。因为“完整备份文件必须呈现数据库在备份完成时间点的所有数据”,所以,数据库必须备份事务B的日志,以便在数据库通过重做此日志还原到时间点7的状态。

对于事务A,其执行的时间早于备份的开始时间,且在数据文件备份期间一直没有结束,是这次完整备份的活动事务。

尽管事务A没有提交,但时间点2的checkpoint已将事务A所做的修改写入到数据文件中,如果完整备份文件没有包含事务A的日志,则这些未提交的修改将无法得到回滚,导致数据不一致的情况发生。

综上所述:

结论2

如果在完整备份前不存在活动事务,则必需的事务日志范围:从备份开始时的LSN到备份结束时的LSN;

如果在完整备份前存在活动事务,则必需的事务日志范围:从最早活动事务开始的LSN到备份结束时的LSN;

在我之前的样例中,因为5条insert语句在数据库备份前已经执行完成并提交了,所以备份文件不会保存这些日志,因而在还原得到的新数据库中看不到这些日志。

至此,我们已经完成了这个定理的证明过程,感谢各位的耐心品读,欢迎大家批评指教。

为什么完整备份不能截断事务日志,布布扣,bubuko.com

时间: 2024-08-24 01:25:31

为什么完整备份不能截断事务日志的相关文章

SQL SERVER完整、差异和事务日志备份及还原(脚本和GUI实现) [原创]

一.完整备份.差异备份和事务日志备份的脚本 --完整备份数据库 BACKUP DATABASE Test_Bak TO DISK = 'E:\20150609_75\bak\Test_bak_full.bak' WITH INIT --差异备份数据库 BACKUP DATABASE Test_Bak TO DISK = 'E:\20150609_75\bak\Test_bak_diff.bak' WITH INIT, DIFFERENTIAL --加上DIFFERENTIAL代表差异备份 --事

解决开启SQL Server sql Always on Group 事务日志增大的问题

配置了Alwayson之后,因为没有只能使用完全恢复模式,不能使用简单或大容量日志模式,所以日志不断增长,不能使用改变恢复模式的方式清空日志 手动操作收缩或截断日志也无效 读了一些文章后发现,有人使用 主要实例脱离可用性组 - 修改为简单恢复模式 -修改回完整恢复模式 - 完整备份 - 加回可用性组 -将辅助副本还原(注意是With NoRECOVERY) - 重启同步 这样虽然可行,但也太麻烦了,对于俺们每天增长70GB的日志文件来说,操作未免太频繁了 也许是我对SQL Server太不熟悉了

SQL Server数据库事务日志存储序列

原文 原文:http://blog.csdn.net/tjvictor/article/details/5251351 ? 如果你的数据库运行在完整或是批量日志恢复模式下,那么你就需要使用作业(job)来定期备份事务日志,保持你的事务文件大小处在一个可管理的范围.当你需要还原事务日志时,你就需要按照创建事务日志的顺序来恢复它们.你可以参考存在msdb..backupset表中的信息来确定还原文件的顺序,使用FirstLSN和LastLSN列的值作参考.当你备份时,这些备份信息就会存在backup

SQL Server中事务日志管理的步骤,第5级:完全恢复模式管理日志

SQL Server中事务日志管理的步骤,第5级:完全恢复模式管理日志 作者:Tony Davis,2012/01/27 系列 本文是进阶系列的一部分:SQL Server中事务日志管理的步骤 当事情进展顺利时,无需特别注意事务日志的作用或工作方式.您只需要确信每个数据库都有正确的备份机制.当出现问题时,了解事务日志对于采取纠正措施很重要,特别是在需要紧急恢复数据库的时间点时!Tony Davis给出了每个DBA都应该知道的正确的细节级别. 在此级别中,我们将回顾在完全恢复模式下工作时进行日志备

十七周-SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志

SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志 By Tony Davis, 2012/01/27 http://www.sqlservercentral.com/articles/Stairway+Series/73785/ 该系列 文是SQL Server中"Stairway系列:事务日志管理的阶梯"的一部分 当事情进展顺利时,不需要特别意识到事务日志的作用或工作原理.你只需要确信每个数据库都有正确的备份机制.当事情出错时,对事务日志的理解对于采取纠正措施

11.3 完整备份

11.3 完整备份 11.3.1 完整备份的过程 完整备份包含了数据库中的所有数据,以及可以恢复这些数据的足够的日志(以便恢复到该备份的结尾). 备份的过程大致包含以下步骤: (1)锁定数据库,阻塞所有的事务. (2)在事务日志中放置一个标志1. (3)释放数据库锁. (4)提取数据文件的所有包含数据的数据页面,把它们写入备份设备.不包含数据的数据页面被跳过,因此备份的文件大小永远不会大于该数据库的数据文件. (5)锁定数据库,阻塞所有事务. (6)在事务日志中放置一个标志2. (7)释放数据库

【转】SQL Server如何截断(Truncate)和收缩(Shrink)事务日志

SQL Server如何截断(Truncate)和收缩(Shrink)事务日志分类: SQL Server数据库备份还原2010-01-25 14:321708人阅读评论(4)举报 当SQL Server截断事务日志时,它仅仅是在虚拟日志文件中做个标记,以便不再使用它,然后准备以重用形式来做备份(假如运载在完整或是批量日志恢复模型).也就是说,在使用简单恢复模型时,事务日志包括如下的日志记录: 当checkpoint发生时,虚拟日志文件1.2不再被使用,因为事务1.2已经被提交了,而且日志记录也

如何截断SQL Server2008+事务日志空间

SQL数据库事务日志记录数据库的任何更改,用户可回滚事务日志来恢复数据,但随着数据库使用时间变长,日志文件也会变得很大. 若要避免数据库的事务日志被填满,例行备份至关重要.做了日志备份后,会释放不活跃的VLF,增加日志的可用空间.但默认情况下备份日志,其日志文件的大小并未变化,如下图 备份前,总大小24.13MB 备份后,总大小仍然为24.13MB,但已用空间占比从93.1%降至11.0% 也就是,已使用日志空间是减小了,但未使用日志空间并未释放.其实,如果磁盘空间足够的话,可以不用收缩空间 那

SQL Server如何截断(Truncate)和收缩(Shrink)事务日志

原文:http://blog.csdn.net/tjvictor/article/details/5253931 ? 当SQL Server截断事务日志时,它仅仅是在虚拟日志文件中做个标记,以便不再使用它,然后准备以重用形式来做备份(假如运载在完整或是批量日志恢复模型).也就是说,在使用简单恢复模型时,事务日志包括如下的日志记录: 当checkpoint发生时,虚拟日志文件1.2不再被使用,因为事务1.2已经被提交了,而且日志记录也不再需要回滚了.然后SQL Server重用虚拟日志文件1.2,