AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 34508
Accepted
Sky
Sky
Asked: 2013-02-11 21:18:19 +0800 CST2013-02-11 21:18:19 +0800 CST 2013-02-11 21:18:19 +0800 CST

恢复数据库上的最新备份

  • 772

我们有一个存储过程,它将备份从数据库到指定位置。有时备份过程运行不止一次。它会导致在同一个文件名上拥有多个备份集。当我们编写 T-SQL 使用这个备份文件恢复目标 db 时,我们如何告诉 SQL 恢复目标数据库上的最新 db 备份集(使用 T-SQL 命令)?

当我们使用 MS SQL 管理工作室恢复备份时,我们可以简单地选择我们想要恢复的备份集。但是我需要使用 T-SQL 运行还原,并且想知道如何确定 SQL 使用最新的数据库备份集进行还原。例如,从下图中,我想恢复最后一个备份集(以黄色突出显示):

在此处输入图像描述

我检查了这个网站,但找不到答案。如果您能提供帮助,我将不胜感激。

谢谢。

sql-server-2008-r2 restore
  • 2 2 个回答
  • 5792 Views

2 个回答

  • Voted
  1. Best Answer
    Stuart Moore
    2013-02-12T06:27:25+08:002013-02-12T06:27:25+08:00

    如果您无法访问原始服务器并且您只有备份文件,那么您需要首先从备份文件中恢复标头以查看其中的内容。

    您可以通过以下方式做到这一点:

    
    create table #headers 
    (
    BackupName              nvarchar(128),
    BackupDescription       nvarchar(255),
    BackupType              smallint,
    ExpirationDate          datetime,
    Compressed              bit,
    Position                smallint,
    DeviceType              tinyint,
    UserName                nvarchar(128),
    ServerName              nvarchar(128),
    DatabaseName            nvarchar(128),
    DatabaseVersion         int,
    DatabaseCreationDate    datetime,
    BackupSize              numeric(20,0),
    FirstLSN                numeric(25,0),
    LastLSN                 numeric(25,0),
    CheckpointLSN           numeric(25,0),
    DatabaseBackupLSN       numeric(25,0),
    BackupStartDate         datetime,
    BackupFinishDate        datetime,
    SortOrder               smallint,
    [CodePage]              smallint,
    UnicodeLocaleId         int,
    UnicodeComparisonStyle  int,
    CompatibilityLevel      tinyint,
    SoftwareVendorId        int,
    SoftwareVersionMajor    int,
    SoftwareVersionMinor    int,
    SoftwareVersionBuild    int,
    MachineName             nvarchar(128),
    Flags                   int,
    BindingID               uniqueidentifier,
    RecoveryForkID          uniqueidentifier,
    Collation               nvarchar(128),
    FamilyGUID              uniqueidentifier,
    HasBulkLoggedData       bit,
    IsSnapshot              bit,
    IsReadOnly              bit,
    IsSingleUser            bit,
    HasBackupChecksums      bit,
    IsDamaged               bit,
    BeginsLogChain          bit,
    HasIncompleteMetaData   bit,
    IsForceOffline          bit,
    IsCopyOnly              bit,
    FirstRecoveryForkID     uniqueidentifier,
    ForkPointLSN            numeric(25,0),
    RecoveryModel           nvarchar(60),
    DifferentialBaseLSN     numeric(25,0),
    DifferentialBaseGUID    uniqueidentifier,
    BackupTypeDescription   nvarchar(60),
    BackupSetGUID           uniqueidentifier,
    CompressedBackupSize    bigint,
    Containment             tinyint
    );
    go
    
    insert into #headers exec('restore headeronly from disk=''c:\DEV\UnitTest.bak''');
    go 
    

    您现在有一个临时表(#headers),其中包含该设备文件中包含的所有备份的详细信息。

    为了找到最新的完整数据库备份,我们仅筛选完整数据库备份 ( backupType=1),然后在设备中查找最新的备份,这将是具有最大 LSN 的备份。这为我们提供了位置值,该值在RESTORE命令中用于向 SQL Server 指定我们要恢复的备份:

    declare @filepos int;
    select top 1 @filepos=Position from #headers where BackupType=1 order by lastlsn desc;
    restore database unittest from Disk=N'c:\DEV\UnitTest.bak' with file=@filepos, recovery, replace;
    

    正如您所说,您仍然可以访问原始服务器,然后我们可以查询 SQL Server 用于存储此信息的 msdb 中的表。

    以下查询假设您在原始服务器上的 SQL 会话中运行它们。如果您不允许这样做,那么您需要考虑使用链接服务器和 4 部分命名。

    有 2 种方法可以指定要查看的备份集。一种是通过备份文件的路径,另一种是通过引用备份设备上的名称。我已将两者都包含在此查询中,并附有一些注释,说明要注释掉的行取决于您的操作方式。

    这将生成一个RESTORE可以在单独的 SSMS 会话中运行的语句。我还在底部提供了一个示例,说明如何自动执行此操作,尽管您需要事先进行一些测试以确保它正在执行您想要的操作。

    
    declare @filepos int, @dbname varchar(50), @devname varchar(50)
    
    /*
    dbname is the name of the database you want to restore. Need this, as it's possible for backups of more than one database to be present in the same backup file or device
    
    devname is either the name of the backup device, or the path to the .bak file
    */
    
    select @dbname='Unittest', @devname='c:\DEV\unittest.bak'
    
    select @filepos=max(c.position) 
    from 
    msdb.dbo.backupmediafamily a 
    inner join msdb.dbo.backupmediaset b on a.media_set_id=b.media_set_id
    inner join msdb.dbo.backupset c on b.media_set_id=c.media_set_id
    where 
    a.physical_device_name=@devname  --use this line if you know the path to the backup
    --a.logical_device_name=@devname --this line if you only know a device name.
    and c.type='D' and c.database_name=@dbname
    
    --This will build the restore statement if you know the device name
    select 'restore database ['+@dbname+'] from '+@devname+' with file='+cast(@filepos as varchar(4))+', recovery, replace' 
    
    --This will build the restore statement if you know the backup file path
    select 'restore database ['+@dbname+'] from disk=N'''+@devname+''' with file='+cast(@filepos as varchar(4))+', recovery, replace' 
    
    /*
    This section only if feeling brave and confident, and you've checked the output previously, as it will execute whatever the generated restore command is, so this could cause a major problem if not checked first, or even overwrite production if run on the wrong box.
    */
    
    declare @restore_cmd varchar(250)
    select @restore = 'restore database ['+@dbname+'] from disk=N'''+@devname+''' with file='+cast(@filepos as varchar(4))+', recovery, replace' 
    exec(@restore)
    
    • 5
  2. Aaron Bertrand
    2013-02-12T05:57:56+08:002013-02-12T05:57:56+08:00

    这应该给你一个开始:

    SELECT 
      s.name, 
      s.backup_start_date, 
      s.backup_finish_date, 
      mf.physical_device_name,
      s.first_lsn, s.last_lsn, s.database_backup_lsn
    FROM 
      msdb.dbo.backupset AS s
    INNER JOIN 
      msdb.dbo.backupmediaset AS ms
      ON s.media_set_id = ms.media_set_id
    INNER JOIN 
      msdb.dbo.backupmediafamily AS mf
      ON ms.media_set_id = mf.media_set_id
    WHERE 
      s.database_name = N'UnitTest' 
    ORDER BY 
      s.backup_finish_date DESC;
    
    • 3

相关问题

  • Postgresql - 使用 recovery.conf 恢复

  • 迁移大型数据库

  • 代理执行的维护计划

  • 如何使用旧的完整备份和当前日志文件恢复数据库

  • 随机化表内容并将它们存储回表中

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve