注意:如果数据库的恢复模式是简单模型(SIMPLE),则无法利用日志文件抢救数据。
在数据文件损坏时,要从日志文件恢复损坏的数据库中的数据,步骤如下:
(1)使用带NO_TRUNCATE子句的BACKUP LOG语句备份损坏的数据库尾日志。NO_TRUNCATE,允许在数据库损坏时备份日志。
解释: NO_TRUNCATE
指定不截断日志,并使数据库引擎尝试执行备份,而不考虑数据库的状态。因此,使用 NO_TRUNCATE 执行的备份可能具有不完整的元数据。该选项允许在数据库损坏时备份日志。 BACKUP LOG 的 NO_TRUNCATE 选项相当于同时指定 COPY_ONLY 和 CONTINUE_AFTER_ERROR。 如果不使用 NO_TRUNCATE 选项,则数据库必须处于 ONLINE 状态。如果数据库处于 SUSPENDED 状态,则可能无法通过指定 NO_TRUNCATE 来创建备份。但是,如果数据库处于 OFFLINE 或 EMERGENCY 状态,则即使使用 NO_TRUNCATE,也不允许执行BACKUP。
(2)使用带NORECOVERY子句的RESTORE DATABASE语句从最后一次完全备份中还原数据库。
(3)如果最后一次完全备份之后存在差异备份,则使用带NORECOVERY子句的RESTORE DATABASE语句还原最后一次完全备份之后的最后一次差异备份。
(4)如果步骤(3)的时间点之后的日志备份,则通过带NORECOVERY子句的RESTORE LOG按照备份先后顺序还原所有的日志备份。
(5)使用带RECOVERY子句的RESTORE LOG语句话还原的步骤(1)备份的数据库尾日志。
use master go --创建测试库 if exists(select object_id('db_test')) begin drop database db_test print 'dd' end go create database db_test on ( name = db_test_data, filename='D:DATABASEDB_TEST.mdf' ), filegroup FG_1( name=db_test_data_1, filename='d:database est_1.ndf' ), filegroup fg_2( name=db_test_data_2, filename='D:databasedb_test_2.ndf' ) log on ( name='db_test_log', filename='d:databasedb_test.ldf' ) go --创建测试表,在各个文件组上 create table db_test.dbo.tb_primary ( id int ) on [primary] create table db_test.dbo.tb_fg_1 ( id int )on fg_1 --文件组备份,做一次完整备份 backup database db_test filegroup ='FG_1' TO DISK ='d:databasedb_test_fg_1.bak' with format --备份后,在文件组FG_1上的表TB_FG_1中插入测试数据 INSERT INTO DB_TEST.DBO.tb_fg_1( id ) values ( 1 ) go --查询表数据是否存在 select * from DB_TEST.DBO.tb_fg_1 /* id ----------- 1 (1 行受影响) */ --停止实例,破坏文件组 shutdown 停掉实例在目录下删除文件: d:databasedb_test_1.ndf,通过此方法来达到破坏数据库的效果。 删除后重启实例。 --验证数据库是否损坏 select * from DB_TEST.DBO.tb_fg_1 /* 消息 945,级别 14,状态 2,第 1 行 由于文件不可访问,或者内存或磁盘空间不足,所以无法打开数据库 'db_test'。有关详细信息,请参阅 SQL Server 错误日志。 */ --备份当前日志 backup log db_test to disk ='d:databasedb_test_log.bak' with format,no_truncate --利用文件组备份恢复破坏的文件 restore database db_test filegroup =N'FG_1' from disk='d:databasedb_test_fg_1.bak' with norecovery --还原数据库尾部日志 restore log db_test from disk='d:databasedb_test_log.bak' with recovery --查询文件组FG_1上的表,tb_fg_1,验证数据是否丢失 select *from db_test.dbo.tb_FG_1 /* id ----------- 1 (1 行受影响) */