事务日志备份与还原.docx
- 文档编号:25732648
- 上传时间:2023-06-12
- 格式:DOCX
- 页数:30
- 大小:406.30KB
事务日志备份与还原.docx
《事务日志备份与还原.docx》由会员分享,可在线阅读,更多相关《事务日志备份与还原.docx(30页珍藏版)》请在冰豆网上搜索。
事务日志备份与还原
14.1事务日志备份与恢复原理
、本章要点
†事务日志备份与恢复原理
†尾日志备份
†产生备份集
†将数据库恢复到故障点
†备份恢复中的疑难问题
一个不懂事务日志的DBA,是很难掌握数据库的精髓的。
事务日志忠实地记录了数据库的活动,所以基于这些记录的活动就可以随心所欲地将数据库的状态恢复到特定的即时点或恢复到故障点。
然而,不是每个DBA都能够正确完成这些操作的。
其中的奥秘在哪里呢?
本章深入研究事务日志备份与恢复操作。
14.1 事务日志备份与恢复原理
下面我们首先来学习事务日志备份与恢复的原理。
14.1.1 事务日志备份与恢复原理
事务日志备份只能与完全恢复模型和大容量日志记录恢复模型一起使用。
在简单模型下,事务日志有可能被破坏,所以事务日志备份可能不连续,不连续的事务日志备份没有意义,因为基于日志的恢复要求日志是连续的。
可以使用事务日志备份将数据库恢复到特定的即时点(如输入多余数据前的那一点)或恢复到故障点。
恢复事务日志备份时,SQLServer2005重做事务日志中记录的所有更改。
当SQLServer2005到达事务日志的最后时,已重新创建了与开始执行备份操作的那一刻完全相同的数据库状态。
如果数据库已经恢复,则SQLServer2005将回滚备份操作开始时尚未完成的所有事务。
一般情况下,事务日志备份比数据库备份使用的资源少。
因此可以比数据库备份更经常地创建事务日志备份。
经常备份将减少丢失数据的危险。
图14-1所示为基于完全恢复模型下的1个完全备份+N个连续的事务日志备份的策略。
如果中间的日志备份02删除或者损坏,则数据库只能恢复到日志备份01的即时点。
图14-1 事务日志备份与恢复原理
假如日志备份01、02和03都是完整的,那么在恢复时,先恢复数据库完全备份,然后依次恢复日志备份01、02和03。
如果要恢复到故障点,就需要看数据库的当前日志是否完整,如果是完整的,可以做一个当前日志的备份,然后依次恢复日志备份04就可以了。
基于事务日志的备份还可以恢复到某个日志备份中间的时刻,称为时点恢复。
比如我们可以在恢复数据库完全备份后,恢复数据库在完全备份和日志备份01中间的某个时刻,这就是时点恢复。
这里的时点必须是合法的(看日志备份的时间),而不能超出日志备份的时间序列,否则系统不会执行。
比如现在只有日志备份01,其时刻为12:
11,假如我们指定恢复到12:
12,那么这样的时点是非法的。
14.1.2 事务日志备份连续的奥秘
连续的事务日志备份是备份和恢复事务日志的基本要求。
那么,什么样的事务日志备份是连续的呢?
LSN(日志序列号)是用于衡量事务日志备份是否连续的基本方法。
1.连续的事务日志备份
当我们通过备份操作形成备份后,我们可以执行restoreheaderonly语句来查看备份集中的事务日志备份,判断其是否连续。
restoreheaderonlyfromdisk='c:
\test2.bak'
查看的结果如图14-2所示。
我们可以得出结论:
该事务日志备份序列是连续的!
为什么呢?
因为这些事务日志备份的LSN首尾连接,后一个日志备份的FirstLSN等于前一个日志备份的LastLSN。
—日志备份(编号2):
FirstLSN:
290179,LastLSN:
290001。
—日志备份(编号3):
FirstLSN:
290001,LastLSN:
300001。
—日志备份(编号4):
FirstLSN:
300001,LastLSN:
300001。
图14-2 实例的事务日志备份序列
因为根据这3个日志备份序列,它记录的事务日志起点是第1个日志备份的FirstLSN:
290179。
终点是最后一个日志备份的LastLSN:
300001。
光盘视频:
\视频\1402.exe(连续的事务日志备份)。
2.不连续的事务日志备份
不连续的日志备份就是指在产生的日志备份序列中,出现了前后首尾不能续接的情况。
这种情况主要发生在初学或者刚开始做DBA的读者身上,不断切换数据库的恢复模型,比如从简单恢复模型切换到完全恢复模型,或者从完全恢复模型切换到大容量日志记录模型,这都是DBA的大忌!
假如你的日志备份出现下列情况。
那么,这样的日志序列LSN首尾不能衔接,无法连接起来执行恢复操作!
—日志备份(编号2):
FirstLSN:
290179,LastLSN:
290001。
—日志备份(编号3):
FirstLSN:
300001,LastLSN:
300001。
提示:
DBA一定要千方百计确保当前日志和日志备份序列的安全,同时还要保证日志序列的完整,判断是否完整的方法就是执行restoreheaderonly语句。
14.1.3 恢复到即时点的奥秘
正是因为有了连续的、完整的事务日志备份序列,配合一个完整数据库备份,我们可以将数据库的状态恢复在日志序列中间的任意一个即时点。
但是,这样做是有前提条件的。
1.正确的完整数据库备份
首先,必须要有一个正确的完整数据库备份,为什么这里要强调“正确”二字呢?
如果读者已经对事务日志的连续性概念有正确认识和理解的话,那么这里的“正确”二字就代表完整数据库备份必须是在第1个日志备份序列的时间点之间完成的。
本书配套光盘收录了一个bak备份文件,包括了1个完整数据库备份和3个连续的事务日志备份,我们看到编号为1的是完整数据库备份,其余3个是事务日志备份。
如图14-3所示。
图14-3 正确的完整数据库备份
完整数据库备份的日志区间是:
290179~290001。
第1个事务日志备份的区间是:
290179~290001。
所以,这里的完整数据库备份就是正确的,因为恢复完整数据库备份,其状态会停留在事务日志备份1中间的某个即时点。
然后可以连续执行事务日志备份来进行恢复。
什么是不正确的完整数据库备份呢?
就是完整数据库备份完成的即时点处于日志备份序列之外。
如图14-4所示。
图14-4 事务日志备份与恢复原理
提示:
永远也不能指望停留在日志备份之外,即时点的完整数据库备份和日志备份能够配合起来进行恢复,因为完整数据库备份和日志备份的日志序列之间产生了中断。
我们可以把这个过程理解为火车的工作机制。
火车头(完整数据库备份)和车厢(日志备份序列)之间首尾相接,所以我们可以从头走到尾。
如果车头和车厢之间发生断裂(不正确的完整数据库备份),我们就只能开走火车头了(将数据库恢复到完整数据库备份完成的即时点)!
同样,如果车厢之间发生断裂(事务日志备份序列断裂),我们就只能走到相连接的部分(恢复连续的日志备份序列),其余部分没有任何意义!
2.正确的即时点
这句话的含义是,永远不要指望将数据库的状态恢复到日志序列记录的LSN区间之外!
这很好理解,因为LSN没有记录的数据库活动,数据库的恢复机制无凭无据,如何恢复?
14.1.4 恢复到故障点的奥秘
无论我们翻阅SQLServer2005的联机丛书,还是我们查阅有关的资料,都会告诉我们:
SQLServer2005拥有将数据库恢复到故障点的能力!
然而,很遗憾的是,没有一本图书好好地告诉我们作者是如何将数据库恢复到故障点的!
我们首先从原理上来理解恢复到故障点的奥秘,如图14-5所示。
图14-5 恢复到故障点的奥秘
从图中我们可以看出,要将数据库恢复到故障点,必须满足3个条件。
1.正确的完整数据库备份
这个很好理解,而且DBA一般都会做。
2.连续的事务日志备份序列
除非存储设备出现故障,否则这个问题也很好解决。
3.正确备份最后一个日志备份和故障点之间的日志
这一点在目前的SQLServer2005的图书中几乎没有提到!
稍微有点实际经验的DBA(这里是指真正从事大型数据库管理的DBA),肯定会意识到这个问题的严重性!
如果我们按照目前的市面上的其他图书去操作,当某个故障发生的时候,我们永远无法将数据库恢复到故障点,因为我们最多只能将数据库恢复到最后一个日志备份完成的时刻,那么,在最后一个日志备份完成的时刻到故障点之间的日志呢?
等待DBA的将是被老板炒鱿鱼的悲惨命运!
提示:
要想将数据库恢复到故障点,就必须深刻理解SQLServer2005的尾日志备份的原理。
很显然,我们必须将这一段特殊的日志(最后日志备份完成时刻~故障点发生时刻)备份下来,从而使从完整数据库备份时刻到故障点时刻的所有日志备份序列是完整的!
如图14-6所示。
图14-6 尾日志备份
14.1.5 尾日志备份
因此,要想完成故障点的恢复,就必须完成尾日志的备份。
接下来我们就来学习尾日志的相关话题。
1.尾日志的存储
首先一个问题,尾日志存储在哪里?
很显然,答案是当前的日志文件中。
当前日志文件保存的内容包括了最后一个成功的日志备份到当前故障点所有的事务。
所以,一旦最后一个日志文件备份和故障点之间数据库的日志文件不幸发生介质故障,比如存放日志文件的硬盘损坏,那么这种情况下,上帝也无法挽救一个DBA的命运!
由此可以看出,日志文件对数据库,对DBA的重要性!
所以如果无法完成尾日志备份,则只能将数据库恢复到创建最后一个事务日志备份时的点。
自上一次事务日志备份后对数据库所做的更改将丢失,必须手工重做。
2.与正常日志备份的区别
与正常日志备份相似,尾日志备份将捕获所有尚未备份的事务日志记录。
但尾日志备份与正常日志备份在下列几个方面有所不同。
—如果数据库损坏或离线,则可以尝试进行尾日志备份。
仅当日志文件未损坏且数据库不包含任何大容量日志更改时,尾日志备份才会成功。
如果数据库包含要备份的、在记录间隔期间执行的大容量日志更改,则仅在所有数据文件都存在且未损坏的情况下,尾日志备份才会成功。
—尾日志备份可使用COPY_ONLY选项独立于定期日志备份进行创建。
仅复制备份不会影响备份日志链。
事务日志不会被尾日志备份截断,并且捕获的日志将包括在以后的正常日志备份中。
这样就可以在不影响正常日志备份过程的情况下进行尾日志备份,例如,为了准备进行在线还原。
—如果数据库损坏,则尾日志可能会包含不完整的元数据,这是因为某些通常可用于日志备份的元数据在尾日志备份中可能会不可用。
使用CONTINUE_AFTER_ERROR进行的日志备份可能会包含不完整的元数据,这是因为此选项将通知进行日志备份而不考虑数据库的状态。
14.2 尾日志备份
对于将数据库恢复到即时点,很好理解也很好操作。
下面我们重点来研究将数据库恢复到故障点时必不可少的操作,即尾日志备份。
但是,需要注意的是,如果在ManagementStudio中按照默认设置是永远无法完成尾日志备份的。
14.2.1 图形化尾日志备份操作
图14-7所示为选择日志备份的数据库的【选项】选项卡。
默认情况下选择的是【截断事务日志】单选按钮,这样将永远无法备份尾日志。
提示:
要完成尾日志备份,需要在图14-7中选择“备份日志尾部,并使数据库处于还原状态”选项。
图14-7 【选项】选项卡
14.2.2 用BackupLog语句完成尾日志备份
也可以直接执行BackupLog语句来完成日志备份。
下面介绍该语句的语法形式。
1.语法形式
BackupLog语句的语法形式如下。
BACKUPLOG{database_name|@database_name_var}
{
TO
[[MIRRORTO
[WITH
[BLOCKSIZE={blocksize|@blocksize_variable}]
[[,]{CHECKSUM|NO_CHECKSUM}]
[[,]{STOP_ON_ERROR|CONTINUE_AFTER_ERROR}]
[[,]DESCRIPTION={'text'|@text_variable}]
[[,]EXPIREDATE={date|@date_var}
|RETAINDAYS={days|@days_var}]
[[,]PASSWORD={password|@password_variable}]
[[,]{FORMAT|NOFORMAT}]
[[,]{INIT|NOINIT}]
[[,]{NOSKIP|SKIP}]
[[,]MEDIADESCRIPTION={'text'|@text_variable}]
[[,]MEDIANAME={media_name|@media_name_variable}]
[[,]MEDIAPASSWORD={mediapassword|@mediapassword_variable}]
[[,]NAME={backup_set_name|@backup_set_name_var}]
[[,]NO_TRUNCATE]
[[,]{NORECOVERY|STANDBY=undo_}]
[[,]{NOREWIND|REWIND}]
[[,]{NOUNLOAD|UNLOAD}]
[[,]RESTART]
[[,]STATS[=percentage]]
[[,]COPY_ONLY]
]
}
2.主要参数
对于其他参数读者可以参阅联机丛书的有关说明。
与备份尾日志有关的主要参数如下。
— NO_TRUNCATE:
只与BACKUPLOG一起使用。
指定不截断日志,并使数据库引擎尝试执行备份,而不考虑数据库的状态。
该选项允许在数据库损坏时备份日志。
— BACKUPLOG的NO_TRUNCATE选项相当于同时指定COPY_ONLY和CONTINUE_AFTER_ERROR。
— NO_LOG|TRUNCATE_ONLY:
通过放弃活动日志以外的所有日志,无须备份复制日志即可删除不活动的日志部分,并截断日志。
该选项会释放空间。
因为并不保存日志备份,所以没有必要指定备份设备。
NO_LOG和TRUNCATE_ONLY是同义的。
使用NO_LOG或TRUNCATE_ONLY截断日志后,记录在日志中的更改不可恢复。
为了进行恢复,请立即执行BACKUPDATABASE以执行完整备份或完整差异备份。
3.使用方法
要备份尾日志,主要使用Truncate_Only参数就可以。
本书的实例代码如下。
BACKUPLOG[db_test]TO DISK=N'C:
\test2.bak'
WITH NO_TRUNCATE,
NOFORMAT,
NOINIT,
NAME=N'db_test-事务日志备份',
SKIP,
NOREWIND,
NOUNLOAD,
NORECOVERY,
STATS=10
GO
14.3 产生备份集
通过前面的学习,我们已经知道SQLServer2005数据库提供了将数据库的状态恢复到故障发生点的功能。
但是这些功能的顺利执行需要有一些前提条件,比如联机日志不能损坏,否则将丢失最后一次日志备份完成时刻到故障点的事务。
很多DBA不了解这其中的奥秘,往往会想当然地认为利用已有的备份日志就可以将数据库恢复到故障点,忘记实际上还需要做一次日志备份才能恢复的奥秘。
接下来我们通过一个具体的实例来完成将数据库恢复到故障点的功能。
14.3.1 案例设计
案例的设计和完成的思路如下。
1.案例步骤
(1)新建数据库db_test,数据库工作在完全恢复模型下,新建表t_clusterindextest,向表中录入1001条数据。
查询得到数据库的日志文件记录的日志区间。
(2)做一次完整数据库备份。
查询得到备份后的数据库的日志区间和备份集中的日志区间。
(3)删除99条数据,产生事务日志,查询得到数据库的日志区间。
(4)第1次完成事务日志备份,按照默认设置就可以,即不是尾日志备份。
查询备份后的数据库日志区间和备份集的日志区间。
(5)删除101条数据,产生事务日志,查询得到数据库的日志区间。
(6)第2次完成事务日志备份,按照默认设置就可以,即不是尾日志备份。
查询备份后的数据库日志区间和备份集的日志区间。
(7)删除表中的1条记录,删除完毕后模拟故障发生。
(8)备份尾日志,然后尝试进行恢复操作。
案例的步骤可以用图14-8来表示。
图14-8 案例步骤
2.验证思路
在备份过程形成的最后的备份集中,我们可以这样来进行验证。
(1)利用完整数据库备份+日志备份1,可以将数据库恢复到删除99条记录的状态。
(2)利用完整数据库备份+日志备份1+日志备份2,可以恢复到将数据库删除200条记录的状态,而无法将数据库恢复到删除201条记录的状态。
(3)由于有尾日志备份,所以利用完整数据库备份+日志备份1+日志备份2+尾日志备份来将数据库恢复到删除201条记录的状态。
3.结论
通过上述实验步骤,说明尾日志备份在将数据库恢复到故障点时的重要性。
读者可以深刻理解联机日志千万不能出故障的根本原因。
14.3.2 产生备份集
接下来介绍如何形成备份集。
1.产生数据库
按照与前面章节同样的办法,创建新的db_test数据库。
创建表t_clusterindextest,生成1001条数据。
执行dbcclog命令查询此时数据库的日志情况如图14-9所示。
—第1条日志记录的CurrentLSN:
0000001d:
0000001a:
0001。
—最后1条日志记录的CurrentLSN:
0000001d:
00000137:
00a2。
图14-9 产生数据库后的日志
2.产生完整数据库备份
(1)按照图14-10所示界面产生完整数据库备份。
图14-10 产生完整数据库备份
(2)执行dbcclog命令查询数据库的日志情况如图14-11所示。
图14-11 产生完整数据库备份后的日志
—第1条日志记录的CurrentLSN:
0000001d:
00000166:
00b3。
—最后1条日志记录的CurrentLSN:
0000001d:
000001b5:
0003。
(3)执行restoreheaderonly命令查询备份集中的日志情况如图14-12所示。
图14-12 产生完整数据库备份后的备份集日志
Ø — FirstLSN:
290179。
Ø — LastLSN:
290001。
3.产生第1次日志备份
(1)执行下列代码删除99条记录。
Deletefromdb_test.dbo.t_clusterindextest
Wheret_t_id<=99
光盘代码:
\代码\1402.sql。
(2)执行dbcclog命令查询数据库的日志情况,如图14-13所示。
图14-13 删除99条数据库后的数据库日志
—第1条日志记录的CurrentLSN:
0000001d:
00000166:
00b3。
—最后1条日志记录的CurrentLSN:
0000001d:
000001ba:
0067。
(3)按照图14-14所示默认设置备份数据库的日志。
也可以执行下列代码完成同样的功能,注意,这里不是完成尾日志备份,而是产生了截断。
BACKUPLOG[db_test]TO DISK=N'C:
\test2.bak'
WITHNOFORMAT,
NOINIT,
NAME=N'db_test-事务日志备份',
SKIP,
NOREWIND,
NOUNLOAD,
STATS=10
GO
光盘代码:
\代码\1403.sql。
(4)执行dbcclog命令查询备份后的数据库日志如图14-15所示。
—第1条日志记录的CurrentLSN:
0000001d:
00000166:
00b3。
—最后1条日志记录的CurrentLSN:
0000001d:
000001ba:
0067。
(5)执行restoreheaderonly命令查询备份集中的日志如图14-16所示。
图14-14 备份事务日志
图14-15 第1次日志备份后的数据库日志
图14-16 产生第1次日志备份后的备份集日志
4.产生第2次日志备份
(1)执行下列代码删除101条记录。
Deletefromdb_test.dbo.t_clusterindextest
Wheret_t_id>99ANDt_t_id<=200
光盘代码:
\代码\1404.sql。
(2)执行dbcclog命令查询删除后的数据库日志如图14-17所示。
图14-17 删除101条记录后的数据库日志
—第1条日志记录的CurrentLSN:
0000001d:
00000166:
00b3。
—最后1条日志记录的CurrentLSN:
0000001e:
00000010:
0008。
(3)第2次备份日志,不备份尾日志。
(4)执行dbcclog命令查询备份后的数据库的日志,如图14-18所示。
—第1条日志记录的CurrentLSN:
0000001e:
00000013:
0001。
—最后1条日志记录的CurrentLSN:
0000001e:
00000027:
0001。
图14-18 第2次事务日志备份后的数据库日志
(5)执行restoreheaderonly命令查询备份集中的日志区间如图14-19所示。
图14-19 第2次日志备份后的备份集日志
5.模拟故障发生
(1)执行下列代码删除1条记录。
delete fromdb_test.dbo.t_clusterindextest
wheret_t_id=555
光盘代码:
\代码\1405.sql。
(2)执行dbcclog命令查询数据库的日志,如图14-20所示。
图14-20 模拟故障发生时的日志
—第1条日志记录的CurrentLSN:
0000001e:
00000013:
0001。
—最后1条日志记录的CurrentLSN:
0000001e:
0000004c:
0005。
6.尾日志备份
(1)选择备份日志,在如图14-21所示的选项卡中选择进行尾日志备份。
(2)也可以通过执行1401.sql来完成同样的过程,执行情况如图14-22所示。
7.数据库日志
所有的操作执行完毕后,执行dbcclog命令查询数据库的日志如图14-23所示。
图14-21 备份尾日志
图14-22 执行尾日志备份的情况
图14-23 执行备份完毕后的数据库日志
—第1条日志记录的CurrentLSN:
0000001e:
00000013:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 事务 日志 备份 还原