抢救损坏数据库中的数据

  注意:如果数据库的恢复模式是简单模型(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 行受影响)
*/
原文地址:https://www.cnblogs.com/junqingday/p/3434494.html