ziqiumeng

前言:

今天花了四个小时的时间总结了下文件备份和还原的相关资料,还算是有些收获吧,该文我参考了某些前辈的文章,下面是相关的链接,我增加了更多的细节和自己的想法:

CareySon 偶像的文章,关于尾日志备份

薛定谔的DBA的实例,关于文件备份和还原

 

一、文件组的创建、备份以及还原

--    测试环境
USE master
GO
--    DROP DATABASE [Demo]
CREATE DATABASE [Demo]
ON  PRIMARY        ( NAME = N\'Demo\', FILENAME = N\'D:\MSSQLDATA\Demo.mdf\' , SIZE = 5120KB , FILEGROWTH = 1024KB ), 
FILEGROUP [FG1] ( NAME = N\'Demo01\', FILENAME = N\'D:\MSSQLDATA\Demo01.ndf\' , SIZE = 5120KB , FILEGROWTH = 1024KB ), 
FILEGROUP [FG2] ( NAME = N\'Demo02\', FILENAME = N\'D:\MSSQLDATA\Demo02.ndf\' , SIZE = 5120KB , FILEGROWTH = 1024KB ), 
FILEGROUP [FG3] ( NAME = N\'Demo03\', FILENAME = N\'D:\MSSQLDATA\Demo03.ndf\' , SIZE = 5120KB , FILEGROWTH = 1024KB )
LOG ON            ( NAME = N\'Demo_log\', FILENAME = N\'D:\MSSQLDATA\Demo_log.ldf\' , SIZE = 5120KB , FILEGROWTH = 10MB)
GO
ALTER DATABASE [Demo] SET RECOVERY FULL WITH NO_WAIT
GO
 
USE [Demo]
GO
--    drop table dbo.TAB
CREATE TABLE dbo.TAB(
    Guid uniqueidentifier not null,
    name nvarchar(50) not null,
    sex     bit not null,
    age  smallint not null,
    indate    datetime not null,
    --CONSTRAINT [PK_TAB] PRIMARY KEY CLUSTERED ([Guid] ASC)ON [FG3]
) ON [FG3]
GO
ALTER TABLE dbo.TAB ADD CONSTRAINT [DF_TAB_Guid] DEFAULT(NEWSEQUENTIALID()) FOR [Guid]
GO
ALTER TABLE dbo.TAB ADD CONSTRAINT [DF_TAB_sex] DEFAULT(1) FOR [sex]
GO
ALTER TABLE dbo.TAB ADD CONSTRAINT [DF_TAB_indate] DEFAULT(GETDATE()) FOR [indate]
GO
 
USE [Demo]
GO
--    drop table dbo.TAB2
CREATE TABLE dbo.TAB2(
    Guid uniqueidentifier not null,
    name nvarchar(50) not null,
    sex     bit not null,
    age  smallint not null,
    indate    datetime not null,
) ON [PRIMARY]
GO
ALTER TABLE dbo.TAB2 ADD CONSTRAINT [DF_TAB2_Guid] DEFAULT(NEWSEQUENTIALID()) FOR [Guid]
GO
ALTER TABLE dbo.TAB2 ADD CONSTRAINT [DF_TAB2_sex] DEFAULT(1) FOR [sex]
GO
ALTER TABLE dbo.TAB2 ADD CONSTRAINT [DF_TAB2_indate] DEFAULT(GETDATE()) FOR [indate]
GO
 
INSERT INTO Demo.dbo.TAB(name ,age) SELECT \'KK\',10
GO 5
INSERT INTO Demo.dbo.TAB2(name ,age) SELECT \'KK\',10
GO 5
 
--    TAB 在文件组 FG3(Demo03) ; TAB2 在文件组 PRIMARY .
 
use master
GO
 
--------------------------------------------------------
/*************** 数据库文件备份还原测试 ***************/
--------------------------------------------------------
 
--    (某个时间)备份文件Demo03
BACKUP DATABASE Demo  
   FILE = \'Demo03\' 
   TO DISK = \'D:\MSSQLDATA\backup\Demo_file_Demo03.bck\'
   WITH INIT , COMPRESSION
GO
 
--    更改数据
UPDATE Demo.dbo.TAB SET name=\'OO\'
GO
UPDATE Demo.dbo.TAB2 SET name=\'OO\'
GO
 
--    备份当前日志, you must add NO_TRUNCATE in statement end,it\'s tail of log, otherwise, you still can\'t query TAB after  restore log
BACKUP LOG Demo  
   TO DISK = \'D:\MSSQLDATA\backup\Demo_log.bck\'
   WITH INIT , NO_TRUNCATE
GO  
 
--    还原文件 Demo03
RESTORE DATABASE [Demo]
    FILE = N\'Demo03\'
    FROM  DISK = N\'D:\MSSQLDATA\backup\Demo_file_Demo03.bck\'
    WITH  NORECOVERY
GO
 
/*此时文件组 FG3(Demo03)不能访问,但其他文件组的表可以正常访问!*/
 
 
--    重做后来的日志
RESTORE LOG [Demo]
    FROM  DISK = N\'D:\MSSQLDATA\backup\Demo_log.bck\'
    WITH  RECOVERY
GO
 
------    完成!
SELECT * FROM Demo.dbo.TAB
SELECT * FROM Demo.dbo.TAB2

备注: no_truncate: 相当于COPY_ONLY和CONTINUE_AFTER_ERROR。使用NO_TRUNCATE备份日志,不会截断日志(仅相当于拷贝日志),所以如果后面有日志备份的话可以跨过这个尾日志,因为它不会截断,也可以在数据库发生错误时使用NO_TRUNCATE备份尾日志。

二、当主文件异常但是日志文件是好的并且SQLSERVER实例运行正常的时候,操作如下:

create table _m(c1 int)
select * from _m

insert _m
select 0

BACKUP DATABASE test TO DISK = \'D:\MSSQLDATA\backup\test.bck\' WITH INIT 
BACKUP LOG test TO DISK = \'D:\MSSQLDATA\backup\test_log.bck\' WITH INIT --, NO_TRUNCATE

insert _m select 1
--关掉SQL SERVER SERVICES,拿掉test DB的MDF文件,让文件处于不可用状态
--开启SQLSERVER
BACKUP LOG test TO DISK = \'D:\MSSQLDATA\backup\test_log1.bck\' WITH INIT , NO_TRUNCATE

--开启SQLSERVER这一步不需要删除挂起的DB也可以做的
RESTORE DATABASE test FROM  DISK = N\'D:\MSSQLDATA\backup\test.bck\' WITH  NORECOVERY
RESTORE LOG test FROM  DISK = N\'D:\MSSQLDATA\backup\test_log.bck\' WITH  NORECOVERY
RESTORE LOG test FROM  DISK = N\'D:\MSSQLDATA\backup\test_log1.bck\' WITH  RECOVERY
--成功了
select * from TEST.DBO._m

三、与二不同的是,连SQLSERVER实例都不能运行的时候,你需要将完整备份和后面需要的所有的日志备份以及ldf文件copy到其他实例上面,我们需要获取最后的一个尾日志。

1、在新的实例上面新建一个名称一样的DB,并且设置成脱机的状态,删除新建数据库的MDF文件,将需要备份的数据库的日志文件替换掉原有的LDF文件。

2、设置DB为联机状态,由于没有mdf文件,DB是不可用的

3、进行尾日志备份(注:如果系统提示权限的不够的相关报错,那你就需要把存放数据库文件的文件夹设置成“完全控制”的权限

 4、依次还原  完整备份--所有的日志备份---最后的尾日志备份

 

以上都是只有一个数据文件的,如果有多个数据文件的话后面有时间更新吧,已经晚上11点多了,休息了。

 

分类:

技术点:

相关文章: