使用Replace选项还原SQL数据库

时间:2016-08-25 08:24:45

标签: sql-server

我试图从各种来源了解REPLACE选项,并没有澄清自己。我使用的是SQL Server 2014版本。

以下2个查询之间有什么区别?两者都完成没有任何错误。有和没有替换。

USE [master]
RESTORE DATABASE [Test] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Backup\MyDatabase.bak'
WITH FILE = 3,  NOUNLOAD,  STATS = 5
GO

Vs的

USE [master]
RESTORE DATABASE [Test] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Backup\MyDatabase.bak'
WITH REPLACE, FILE = 3,  NOUNLOAD,  STATS = 5
GO

当我尝试使用现有数据库(Test2)的.mdf和.ldf替换时,出现错误。到目前为止,我的理解是我可以使用名称[Test2]恢复[Test1] db的备份(这已存在于我的服务器中,并且Test1 DB也存在)。

我收到了REPLACE的声明"使用另一个数据库的备份恢复现有数据库。"来自Microsoft Link之一。

USE [master]
RESTORE DATABASE [Test2] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Backup\MyDatabase.bak'
WITH REPLACE, FILE = 3,  NOUNLOAD,  STATS = 5
GO

错误:

Msg 1834, Level 16, State 1, Line 2
The file 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\test1.mdf' cannot be overwritten.  It is being used by database 'test1'.
Msg 3156, Level 16, State 4, Line 2
 'test1' cannot be restored to 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\test1.mdf'. Use WITH MOVE to identify a valid location for the file.
Msg 1834, Level 16, State 1, Line 2

REPLACE选项的目的是什么以及它在场景后面替换的内容。任何人都可以用任何一个例子来解释吗?

2 个答案:

答案 0 :(得分:0)

REPLACE选项的目的是允许您覆盖数据库名称(使用与备份不同的名称来覆盖现有数据库)。您的错误是由于您试图从要求还原的数据库中覆盖另一个数据库的文件引起的。因此,可以还原Test2数据库,但破坏了Test1数据库文件(Test1.MDB和Test1.LDB)。如果不使用MOVE子句,则RESTORE命令将使用与BACKUP相同的文件名。可能不是一个好主意,否则事情将变得非常混乱。 (Test2数据库指向Test1.mdb和Test1.ldb)

以下我的脚本演示了该问题。 我创建数据库Test1。 我备份它。 我尝试使用REPLACE将其还原到Test2。它失败,因为Test1数据库正在使用Test1.mdb和Test1.ldb。 我删除了Test1数据库。 我尝试使用REPLACE将其还原到Test2,现在可以使用。 (但是正在使用Test1.mdb和Test1.ldb)。

CREATE DATABASE [Test1]
 ON  PRIMARY 
( NAME = N'Test1', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Test1.mdf' , SIZE = 8192KB , FILEGROWTH = 65536KB )
 LOG ON 
( NAME = N'Test1_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Test1_log.ldf' , SIZE = 8192KB , FILEGROWTH = 65536KB )
GO
BACKUP DATABASE [Test1] TO  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\Test1.bak' WITH  COPY_ONLY, NOFORMAT, NOINIT,  NAME = N'Test1-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO
--Fails... It is being used by database 'Test1'.
RESTORE DATABASE [Test2] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\Test1.bak'
WITH REPLACE,   NOUNLOAD,  STATS = 5
GO
DROP DATABASE Test1
GO
--Now works, but the files are Test1.mdf and Test1.ldf
RESTORE DATABASE [Test2] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\Test1.bak'
WITH REPLACE,   NOUNLOAD,  STATS = 5
GO
DROP DATABASE Test2
GO
CREATE DATABASE [Test2]
 ON  PRIMARY 
( NAME = N'Test1', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Test2.mdf' , SIZE = 8192KB , FILEGROWTH = 65536KB )
 LOG ON 
( NAME = N'Test1_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Test2_log.ldf' , SIZE = 8192KB , FILEGROWTH = 65536KB )
GO
--Now the same command works,  because Test1.mdf and Test1.ldf are not in use.
RESTORE DATABASE [Test2] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\Test1.bak'
WITH REPLACE,   NOUNLOAD,  STATS = 5
GO

这是Microsoft对REPLACE选项的解释:

https://docs.microsoft.com/en-us/sql/t-sql/statements/restore-statements-transact-sql?view=sql-server-2017#REPLACEoption

REPLACE选项的影响 只有在仔细考虑后,才应很少使用REPLACE。恢复通常可以防止意外地用其他数据库覆盖数据库。如果当前服务器上已经存在RESTORE语句中指定的数据库,并且指定的数据库系列GUID与备份集中记录的数据库系列GUID不同,则不会还原该数据库。这是重要的保障措施。

REPLACE选项将覆盖恢复正常执行的一些重要安全检查。覆盖的检查如下:

使用另一个数据库的备份还原现有数据库。

使用REPLACE选项,还原可以使您用备份集中的任何数据库覆盖现有数据库,即使指定的数据库名称与备份集中记录的数据库名称不同。这可能导致意外地用另一个数据库覆盖数据库。

使用完整日志记录或批量日志记录恢复模型还原数据库,其中未进行尾日志备份并且未使用STOPAT选项。

使用REPLACE选项,您可能会丢失已提交的工作,因为最近写入的日志尚未备份。

覆盖现有文件。

例如,一个错误可能允许覆盖错误类型的文件(如.xls文件),或被另一个不在线的数据库使用的文件。尽管已还原的数据库已完成,但是如果覆盖现有文件,则可能会导致任意数据丢失。

答案 1 :(得分:0)

我的发现方式如下:

  • 使数据库脱机->任务->使数据库脱机
  • 在Windows资源管理器中转到数据库并删除mdf和log.ldf
    • C:\ Program Files \ Microsoft SQL Server \ MSSQL13.MSSQLSERVER \ MSSQL \ DATA \ Test1.mdf
  • 让您的Sql脚本运行

就是这样。

总的来说,我认为最好创建一个备份并将其还原。在数据库中。

  • 右键单击数据库->任务->脱机
  • 右键单击数据库->任务->恢复->数据库
  • 选择页面->常规->在设备下选择文件
  • 选择页面->选项->标记覆盖现有数据库(使用替换)
  • 让它运行