• 文件备份和还原


    前言:

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

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

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

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

    --    测试环境
    USE master
    GO
    --    DROP DATABASE [Demo]
    CREATE DATABASE [Demo]
    ON  PRIMARY        ( NAME = N'Demo', FILENAME = N'D:MSSQLDATADemo.mdf' , SIZE = 5120KB , FILEGROWTH = 1024KB ), 
    FILEGROUP [FG1] ( NAME = N'Demo01', FILENAME = N'D:MSSQLDATADemo01.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ), 
    FILEGROUP [FG2] ( NAME = N'Demo02', FILENAME = N'D:MSSQLDATADemo02.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ), 
    FILEGROUP [FG3] ( NAME = N'Demo03', FILENAME = N'D:MSSQLDATADemo03.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB )
    LOG ON            ( NAME = N'Demo_log', FILENAME = N'D:MSSQLDATADemo_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:MSSQLDATAackupDemo_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:MSSQLDATAackupDemo_log.bck'
       WITH INIT , NO_TRUNCATE
    GO  
     
    --    还原文件 Demo03
    RESTORE DATABASE [Demo]
        FILE = N'Demo03'
        FROM  DISK = N'D:MSSQLDATAackupDemo_file_Demo03.bck'
        WITH  NORECOVERY
    GO
     
    /*此时文件组 FG3(Demo03)不能访问,但其他文件组的表可以正常访问!*/
     
     
    --    重做后来的日志
    RESTORE LOG [Demo]
        FROM  DISK = N'D:MSSQLDATAackupDemo_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:MSSQLDATAackup	est.bck' WITH INIT 
    BACKUP LOG test TO DISK = 'D:MSSQLDATAackup	est_log.bck' WITH INIT --, NO_TRUNCATE
    
    insert _m select 1
    --关掉SQL SERVER SERVICES,拿掉test DB的MDF文件,让文件处于不可用状态
    --开启SQLSERVER
    BACKUP LOG test TO DISK = 'D:MSSQLDATAackup	est_log1.bck' WITH INIT , NO_TRUNCATE
    
    --开启SQLSERVER这一步不需要删除挂起的DB也可以做的
    RESTORE DATABASE test FROM  DISK = N'D:MSSQLDATAackup	est.bck' WITH  NORECOVERY
    RESTORE LOG test FROM  DISK = N'D:MSSQLDATAackup	est_log.bck' WITH  NORECOVERY
    RESTORE LOG test FROM  DISK = N'D:MSSQLDATAackup	est_log1.bck' WITH  RECOVERY
    --成功了
    select * from TEST.DBO._m

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

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

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

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

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

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

  • 相关阅读:
    7
    6
    5
    3
    4
    2
    1
    寒假工作经历
    软件工程第三周的总结
    软件工程第三周的学习报告 html<input> final finally finalize 的比较 BigInteger
  • 原文地址:https://www.cnblogs.com/ziqiumeng/p/10703270.html
Copyright © 2020-2023  润新知