利用bak文件恢复数据库问题小结

对备份的基础理解:

--完整备份:完整备份会备份所有数据的区和少量的日志(日志文件用于恢复数据保持数据一致性)。由于差异备份需要依据最后一次完整备份,因此完整备份会清楚一些分配位图数据。

--差异备份:差异备份是针对完全备份:备份上一次的完全备份后发生变化的所有修改过的数据区(注意不是数据页),差异备份不是增量进行,不会修改分配位图数据。

--事务日志备份:在完整恢复模式或大容量日志恢复模式下,如果事务日志自日志链建立后没有进行过日志备份,则备份最最后一次完整备份或差异备份后的所有日志,否则备份自上一次日志备份后的所有日志。默认情况下,日志备份后会截断日志,但如果不想截断日志,可以使用WITH COPY_ONLY选项。 事务日志备份属于增量备份。如果在事务日志备份包含的日志期间内,数据库被切换成大容量日志恢复模式,则事务日志备份会包含事务日志和该区间内大日志操作所修改的数据区,此事务日志备份还原时不能指定还原点。如果数据库一直处于完整恢复模式下生成的事务日志备份,还原时可以指定还原点进行还原。

--文件备份:在备份时指定文件或文件组进行备份。

--日志链:连续的日志备份序列称为“日志链”。日志链从数据库的完整备份开始,只有数据库再次切换到简单恢复模式才会破坏日志链,当数据库再次切换成完整恢复模式或大容量日志恢复模式后,断裂的日志链可以使用差异备份连接上,或可以使用完整备份开始一个新的日志链。

--尾日志: 自最后一次日志备份后产生的日志,为防止丢失,当对正在运行的数据库进行还原而不指定 REPLACE,会提示出错,此时可使用 BACK LOG WITH NORECOVERY来备份日志并将数据设置为还原状态。

完整备份和差异备份中会带有少量的事务日志以保持数据一致性(如果回滚未提交事务修改的数据),但完整备份和差异备份都不会截断日志。

完整备份和差异备份与日志备份三种备份可以同时运行,三者间不会影响。

在备份数据或备份日志时不会对数据加锁,但是由于备份会导致 IO压力,因此可能影响查询速度(看起来像数据被锁无法访问),在备份大事务日志操作产生的数据区时,备份会对文件加锁,以防止其他进程提交 CHECKPOINT.

RESTORE FILELISTONLY FROM DISK = 'E:bs8.1Dvbbs8.1.0_SQLDatasq_ebendegfzds_bkp_1.bak'

go

以上文字列出所要恢复的.bak文件的逻辑名(logicalName)本例中.mdf和.ldf的逻辑名分别为"sq_ebende_data"和"sq_ebende_log",利用逻辑名来对数据库进行恢复

的语句为:

restore database 数据库名

from disk='备份文件所在路径'

with

move '.mdf文件逻辑文件名'

 to '.mdf要恢复到的路径'

move '.log文件的逻辑文件名'

 to '.log要恢复到的路径'

go

下面是实例:

其中红色部分为逻辑文件名,如果不正确,会出现如下错误

服务器: 消息 3234,级别 16,状态 2,行 2
逻辑文件 'sq_ebende' 不是数据库 'sq_ebende' 的一部分。请使用 RESTORE FILELISTONLY 来列出逻辑文件名。

逻辑文件名固定(数据库一旦创建)如 'sq_ebende_data' ,'sq_ebende_log';数据库文件名称可变  如 ‘E:\Datasq_ebende.ldf'

restore database sq_ebende

from disk='E:Datasq_ebendeg_bkp_1.bak'
with replace,move 'sq_ebende_data'

 to 'E:Datasq_ebende.mdf',
move 'sq_ebende_log'
 to 'E:\Datasq_ebende.ldf'
go

由于,备份文件名是‘sq_ebende_bkp_1.bak’易让人以为逻辑文件名是sq_ebende,其实并不一定是,最好用RESTORE FILELISTONLY FROM DISK = ’xxx‘ 来查看

恢复数据库到指定的时间点(例:故障发生前几分钟),这种情况下需要备份活动日志,通常 备份活动日志的时候 不需要截断日志(减少对日志链的影响)需要加NO_TRUNCATE的参数

例 :backup log mytest to disk = 'D:logbackupmytestmytest_last9t.trc' with no_truncate

  restore database mytest from  disk = 'D:databackupmytestmytest_52_20151222.full' with norecovery

  restore database mytest from  disk = 'D:databackupmytestmytest_52_20151222.diff' with norecovery

  restore log mytest from disk = 'D:logbackupmytestmytest_last9t.trn' with recovery,stopat = 'xxxxxx'

若需要备份日志的尾部并使数据库处于 RESTORING 状态的时候(数据库文件未损害 ,仅仅是想恢复几分钟前数据) 可以使用NORECOVETY参数进行备份,可以跟NO_TRUNCATE参数联合使用(减少对日志链的影响)

例:backup log mytest to disk = 'D:logbackupmytestmytest_last9t.trn' with norecovery,no_truncate

  restore log mytest from disk = 'D:logbackupmytestmytest_last9t.trn' with recovery,stopat = 'xxxxxx'

  即可恢复几分钟前数据,无需还原完整备份了,节省数据库的恢复时间,减少损失,用于故障时间点明确的情况,若是故障时间点不确定 要讲recovery参数换成standby = ‘xxx’ (绝对路径下的文件)

具体实例:

-- 还原到一个新库  逻辑名不可变 ,数据库文件名称可变
restore database xxxxxDBpast 
from disk = 'F:DBbackupxxxxxDBxxxxxDB_53_20151227.full' 
with norecovery ,stats = 10
,move 'xxxxxDB' to  'E:DatabasexxxxxDBpast.mdf'

--其中'xxxxxDB'  为原数据库的逻辑名 ; 'E:DatabasexxxxxDBpast.mdf' 为数据库文件名称
,move 'xxxxxDB_log' to 'E:DatabasexxxxxDBpast_log.ldf'
--还原到一个已经存在的库
restore database xxxxxDBpast
 from disk = 'F:DBbackupxxxxxDBxxxxxDB_2_20160103.full' 
 with norecovery ,stats = 10
 ,replace
,move 'xxxxxDB' to  'E:DatabasexxxxxDBpast.mdf'
,move 'xxxxxDB_log' to 'E:DatabasexxxxxDBpast_log.ldf'
-- 还原差异备份 restore database xxxxxDBpast from disk = 'F:DBbackupxxxxxDBxxxxxDB_2_20160109.diff' with norecovery ,stats = 10 --还原日志备份 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45371.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45375.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45379.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45383.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45387.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45391.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45395.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45399.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45403.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45407.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45411.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45415.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45419.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45423.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45427.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45431.trn' with norecovery ,stats = 10 restore log xxxxxDBpast from disk = 'F:ackuplogxxxxxDBxxxxxDB_No45435.trn' with standby = 'd:yucbtempaa' ,stats = 10,stopat = '2016-01-09 17:20:06.820' -- standby 后指定一个任意文件的绝对路径,可以多次还原时间点(当还原点不确定的时候)。 -- 可到具体的备份日志的路径下 dir *.trn /a-d/b/s 列出所有的日志文件名

restore 参数介绍:

[ RECOVERY | NORECOVERY | STANDBY ]
支持的语句: RESTORE
RECOVERY
指示还原操作回滚任何未提交的事务。 在恢复进程后即可随时使用数据库。 如果既没有指定 NORECOVERY 和 RECOVERY,也没有指定 STANDBY,则默认为 RECOVERY。
如果安排了后续 RESTORE 操作(RESTORE LOG 或从差异数据库备份 RESTORE DATABASE),则应改为指定 NORECOVERY 或 STANDBY。
从 SQL Server 早期版本中还原备份集时,可能要求将数据库升级。 如果指定了 WITH RECOVERY,升级将自动进行。 有关详细信息,请参阅应用事务日志备份 (SQL Server)。
注意 注意
如果省略 FROM 子句,则必须在 WITH 子句中指定 NORECOVERY、RECOVERY 或 STANDBY。
NORECOVERY
指示还原操作不回滚任何未提交的事务。 如果稍后必须应用另一个事务日志,则应指定 NORECOVERY 或 STANDBY 选项。 如果既没有指定 NORECOVERY 和 RECOVERY,也没有指定 STANDBY,则默认为 RECOVERY。 使用 NORECOVERY 选项执行脱机还原操作时,数据库将无法使用。
还原数据库备份和一个或多个事务日志时,或者需要多个 RESTORE 语句(例如还原一个完整数据库备份并随后还原一个差异数据库备份)时,RESTORE 需要对所有语句使用 WITH NORECOVERY 选项,但最后的 RESTORE 语句除外。 最佳方法是按多步骤还原顺序对所有语句都使用 WITH NORECOVERY,直到达到所需的恢复点为止,然后仅使用单独的 RESTORE WITH RECOVERY 语句执行恢复。
当 NORECOVERY 选项用于文件或文件组还原操作时,它会强制数据库在还原操作结束后保持还原状态。 这在以下情况中很有用:
还原脚本正在运行且始终需要应用日志。
使用文件还原序列,并且在两次还原操作之间不能使用数据库。
在某些情况下,RESTORE WITH NORECOVERY 会将前滚集滚动到足够靠前的位置,使它与数据库一致。 在这种情况下将不会出现回滚,数据仍会保持脱机状态,正如使用该选项预期出现的情况一样。 但数据库引擎会发出一条信息性消息,表明现在可以用 RECOVERY 选项恢复前滚集。
STANDBY =standby_file_name
指定一个允许撤消恢复效果的备用文件。 STANDBY 选项可以用于脱机还原(包括部分还原), 但不能用于联机还原。 尝试为联机还原操作指定 STANDBY 选项将会导致还原操作失败。 如果必须升级数据库,也不允许使用 STANDBY 选项。
备用文件用于为 RESTORE WITH STANDBY 的撤消过程中修改的页面保留一个“写入时副本”预映像。 备用文件允许用户在事务日志还原期间以只读方式访问数据库,并允许数据库用于备用服务器情形,或用于需要在日志还原操作之间检查数据库的特殊恢复情形。 执行完 RESTORE WITH STANDBY 操作之后,下一个 RESTORE 操作会自动删除撤消文件。 如果在下一个 RESTORE 操作之前手动删除了这个备用文件,则必须重新还原整个数据库。 当数据库处于 STANDBY 状态时,您应将这个备用文件视为和任何其他数据库文件同样重要。 该文件与其他数据库文件不同,数据库引擎仅在活动还原操作过程中持续打开该文件。
standby_file_name 指定了一个备用文件,其位置存储在数据库的日志中。 如果某个现有文件使用了指定的名称,该文件将被覆盖,否则数据库引擎会创建该文件。
给定备用文件的大小要求取决于由还原操作过程中未提交的事务所导致的撤消操作数。

如何快速截断日志:

--在SQL Server 2005 中,可用使用 BACKUP LOG WITH TRUNCATE_ONLY来迅速清理日志,该命令在 SQL Server2008 及更高版本上被去除。

--BACKUP LOG WITH TRUNCATE_ONLY --该语句相当于将数据库改为简单恢复模式后又改为完整恢复模式,在该语句运行后至最近一次完整备份区间,数据库相当于运行在简单恢复模式下,所有活动日志在 checkpoint后被丢弃,且无法对数据库进行日志备份。

​ --BACKUP LOG TO DISK='nul' --nul并非null 的错误拼写, nul可以被看成一个虚拟文件,所有写入到 nul文件里的数据都被丢弃,对 SQL Server而言,nul 与其他真实存在的文件一样, SQL SERVER会扫描所有活动日志,将该日志格式化后写入 nul文件,数据写入到nul文件后被操作系统丢弃,然后由操作系统返回确认信息给 SQL Server,然后将活动日志标记为已日志备份,该活动日志所在空间可被 reuse。 --BACKUP LOG TO DISK='nul' 相当于正常备份日志然后删除日志文件,并不破坏备份日志链。

--总结:在SQL SERVER 2008 及以后版本中,可以通过修改数据库恢复模式方式来实现 TRUNCATE_ONLY功能,对于数据库已做镜像且数据库日志巨大的情况,如果不需要当前日志,可以使用 BACKUP LOG TO DISK='nul'方式来备份日志然后收缩。

--注意: --1>BACKUP LOG TO DISK='nul' 会导致日志不可用再恢复。

如果你是蜗牛,那你就不必害怕自己前进的缓慢,相信你自己,因为你的脚步永远不会落空,只要你一步步的向上爬,金字塔也必定被你踩在脚下。
原文地址:https://www.cnblogs.com/lx823706/p/5062544.html