恢复数据库备份时出错

时间:2012-05-24 16:11:57

标签: sql-server database exception-handling restore sql-server-2012

使用SQL Server 2012恢复使用以前版本(SQL Server 2008)创建的备份时出错。我实际上有几个相同数据库的备份文件(在过去的不同时间拍摄)。最新的恢复没有任何问题;但是,其中一个出现以下错误:

  

System.Data.SqlClient.SqlError:文件的目录查找   “C:\ PROGRAM FILES \ MICROSOFT SQL   SERVER \ MSSQL.1 \ MSSQL \ DATA \ MYDB_ABC.MDF“操作失败   系统错误3(系统找不到指定的路径。)。   (Microsoft.SqlServer.SmoExtended)

这是一台x64计算机,我的数据库文件位于以下位置:c:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL

我不明白为什么它会尝试恢复MSSQL.1而不是MSSQL11.MSSQLSERVER

13 个答案:

答案 0 :(得分:33)

听起来备份是在路径与您的路径不匹配的机器上进行的。尝试使用T-SQL而不是UI执行备份。还要确保您指定的路径确实存在,并且那里还没有这些mdf / ldf文件的副本。

RESTORE DATABASE MYDB_ABC FROM DISK = 'C:\path\file.bak'
WITH MOVE 'mydb' TO 'c:\valid_data_path\MYDB_ABC.mdf',
MOVE 'mydb_log' TO 'c:\valid_log_path\MYDB_ABC.ldf';

答案 1 :(得分:9)

备份存储数据库文件的原始位置,默认情况下,尝试还原到同一位置。由于您的新服务器安装在新目录中,并且可能是旧目录不再存在,您需要更改默认值中的目录以匹配您希望它使用的位置。

根据您恢复数据库的方式,执行此操作的方式会有所不同。如果您正在使用SSMS,请查看选项卡和列表,直到找到文件列表及其关联的磁盘位置 - 然后您可以在还原之前编辑这些位置。

答案 2 :(得分:5)

我已经设法通过代码完成此操作。这还不够

Restore bkp = new Restore();
bkp.PercentCompleteNotification = 1;
bkp.Action = RestoreActionType.Database;
bkp.Database = sDatabase;
bkp.ReplaceDatabase = true;

必须使用要重定位的文件的名称和路径填充RelocateFiles属性。对于每个文件,您必须指定文件的名称和新的物理路径。所以我所做的就是查看我正在恢复的数据库的PrimaryFilePath,并将其用作物理位置。像这样:

if (!string.IsNullOrEmpty(sDataFileName) && !File.Exists(sDataFileName))
{
   if (originaldb != null)
   {
      if (string.Compare(Path.GetDirectoryName(sDataFileName), originaldb.PrimaryFilePath, true) != 0)
      {
         string sPhysicalDataFileName = Path.Combine(originaldb.PrimaryFilePath, sDatabase + ".MDF");
         bkp.RelocateFiles.Add(new RelocateFile(sLogicalDataFileName, sPhysicalDataFileName));
      }                  
   }
}

日志文件相同。

答案 3 :(得分:5)

我遇到了同样的问题,这修复了它没有任何C#代码:

USE [master]
ALTER DATABASE [MyDb] 
SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE [MyDb] 
FROM  DISK = N'D:\backups\mydb.bak' 
WITH  FILE = 1,  
MOVE N'MyDb' TO N''c:\valid_data_path\MyDb.mdf',  
MOVE N'MyDb_log' TO N'\valid_log_path\MyDb.ldf',  
NOUNLOAD,  
REPLACE,  
STATS = 5
ALTER DATABASE [MyDb] SET MULTI_USER

GO

答案 4 :(得分:3)

还原时,在“文件”下,选中“将所有文件重新定位到文件夹”

check 'Relocate all files to folder'

答案 5 :(得分:2)

正如已经多次说过的那样,恢复mdf和ldf文件的新旧路径不匹配的备份可能会导致此错误。这里有几个很好的例子,说明如何使用SQL来处理它,但是直到我意识到在我的情况下我需要包含' .mdf'和' .ldf'来自“移动”部分的扩展声明,例如:

RESTORE DATABASE [SomeDB] 
FROM DISK = N'D:\SomeDB.bak' 
WITH MOVE N'SomeDB.mdf' TO N'D:\SQL Server\MSSQL12.MyInstance\MSSQL\DATA\SomeDB.mdf', 
MOVE N'SomeDb_log.ldf' TO N'D:\SQL Server\MSSQL12.MyInstance\MSSQL\DATA\SomeDB_log.ldf'

希望能为某人节省一些痛苦,我无法理解为什么SQL建议我在我已经这样做时需要使用WITH MOVE选项。

答案 6 :(得分:0)

Please try to uncheck the “Tail-Log Backup” option on the Options page of the Restore Database dialog

答案 7 :(得分:0)

尝试重新启动SQL服务。为我工作。

答案 8 :(得分:0)

以防这对直接使用Powershell的人(使用SMO库)有用,在这种特殊情况下也有辅助数据文件。我通过杀死任何打开的进程然后进行恢复来增强脚本。

Import-module SQLPS
$svr = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "server name";
$svr.KillAllProcesses("database_name");
$RelocateData1 = New-Object "Microsoft.SqlServer.Management.Smo.RelocateFile, Microsoft.SqlServer.SmoExtended, Version=13.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" ("primary_logical_name","C:\...\SQLDATA\DATA\database_name.mdf")
$RelocateData2 = New-Object "Microsoft.SqlServer.Management.Smo.RelocateFile, Microsoft.SqlServer.SmoExtended, Version=13.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" ("secondary_logical_name_2","C:\...\SQLDATA\DATA\secondary_file_2.mdf")
$RelocateData3 = New-Object "Microsoft.SqlServer.Management.Smo.RelocateFile, Microsoft.SqlServer.SmoExtended, Version=13.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" ("secondary_logical_name_3","C:\...\SQLDATA\DATA\secondary_file_3.mdf")
$RelocateLog = New-Object "Microsoft.SqlServer.Management.Smo.RelocateFile, Microsoft.SqlServer.SmoExtended, Version=13.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" ("database_name_log","C:\...\SQLDATA\LOGS\database_name_log.ldf")
Restore-SqlDatabase -ServerInstance "server-name" -Database "database_name" -BackupFile "\\BACKUPS\\database_name.bak" -RelocateFile @($RelocateData1, $RelocateData2, $RelocateData3, $RelocateLog) -ReplaceDatabase

答案 9 :(得分:0)

您应该从脚本中删除这些行。

CONTAINMENT = NONE
 ON  PRIMARY 
( NAME = N'StudentManagement', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\StudentManagement.mdf' , SIZE = 10240KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'StudentManagement_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\StudentManagement_log.ldf' , SIZE = 5696KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [StudentManagement] SET COMPATIBILITY_LEVEL = 110
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [StudentManagement].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [StudentManagement] SET ANSI_NULL_DEFAULT OFF 
GO
ALTER DATABASE [StudentManagement] SET ANSI_NULLS OFF 
GO
ALTER DATABASE [StudentManagement] SET ANSI_PADDING OFF 
GO
ALTER DATABASE [StudentManagement] SET ANSI_WARNINGS OFF 
GO
ALTER DATABASE [StudentManagement] SET ARITHABORT OFF 
GO
ALTER DATABASE [StudentManagement] SET AUTO_CLOSE OFF 
GO
ALTER DATABASE [StudentManagement] SET AUTO_CREATE_STATISTICS ON 
GO
ALTER DATABASE [StudentManagement] SET AUTO_SHRINK OFF 
GO
ALTER DATABASE [StudentManagement] SET AUTO_UPDATE_STATISTICS ON 
GO
ALTER DATABASE [StudentManagement] SET CURSOR_CLOSE_ON_COMMIT OFF 
GO
ALTER DATABASE [StudentManagement] SET CURSOR_DEFAULT  GLOBAL 
GO
ALTER DATABASE [StudentManagement] SET CONCAT_NULL_YIELDS_NULL OFF 
GO
ALTER DATABASE [StudentManagement] SET NUMERIC_ROUNDABORT OFF 
GO
ALTER DATABASE [StudentManagement] SET QUOTED_IDENTIFIER OFF 
GO
ALTER DATABASE [StudentManagement] SET RECURSIVE_TRIGGERS OFF 
GO
ALTER DATABASE [StudentManagement] SET  DISABLE_BROKER 
GO
ALTER DATABASE [StudentManagement] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
GO
ALTER DATABASE [StudentManagement] SET DATE_CORRELATION_OPTIMIZATION OFF 
GO
ALTER DATABASE [StudentManagement] SET TRUSTWORTHY OFF 
GO
ALTER DATABASE [StudentManagement] SET ALLOW_SNAPSHOT_ISOLATION OFF 
GO
ALTER DATABASE [StudentManagement] SET PARAMETERIZATION SIMPLE 
GO
ALTER DATABASE [StudentManagement] SET READ_COMMITTED_SNAPSHOT OFF 
GO
ALTER DATABASE [StudentManagement] SET HONOR_BROKER_PRIORITY OFF 
GO
ALTER DATABASE [StudentManagement] SET RECOVERY SIMPLE 
GO
ALTER DATABASE [StudentManagement] SET  MULTI_USER 
GO
ALTER DATABASE [StudentManagement] SET PAGE_VERIFY CHECKSUM  
GO
ALTER DATABASE [StudentManagement] SET DB_CHAINING OFF 
GO
ALTER DATABASE [StudentManagement] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) 
GO
ALTER DATABASE [StudentManagement] SET TARGET_RECOVERY_TIME = 0 SECONDS 

答案 10 :(得分:0)

当您使用一个MSSQL Studio进行备份(连接到旧服务器)和还原(连接到新服务器)时,通常会发生这种情况。只要确保您在正确的服务器上执行还原即可。在UI或dou的左窗格中检查服务器名称和IP。

答案 11 :(得分:0)

如果使用C#执行此操作,并且物理路径不同,则需要使用RelocateFiles,这里也提到了一个答案。

在大多数情况下,以下代码将起作用:

  1. 您只是从其他地方恢复数据库的备份,否则就意味着完全相同。例如,将生产副本复制到本地Db。

  2. 您没有使用非典型的数据库布局,例如,行文件分布在多个磁盘上的多个文件中。

此外,仅在首次还原时才需要以下内容。一旦成功完成一次还原,就已经在Sql Server中为您设置了以下文件映射。但是,第一次-将bak文件还原到空白db-您基本上必须说:“是的,请在默认的本地位置使用Db文件,而不是吓坏了”,并且需要告诉它将内容保留在其中。奇怪的是,告诉它重新安置他们在同一地方:

var dbDataFile = db.FileGroups[0].Files[0];
restore.RelocateFiles.Add(new RelocateFile(dbDataFile.Name, dbDataFile.FileName));
var dbLogFile = db.LogFiles[0];
restore.RelocateFiles.Add(new RelocateFile(dbLogFile.Name, dbLogFile.FileName));

为了更好地弄清典型情况是什么,以及如何进行还原,以下是将.bak文件还原到本地计算机的完整代码:

var smoServer = new Microsoft.SqlServer.Management.Smo.Server(
    new Microsoft.SqlServer.Management.Common.ServerConnection(sqlServerInstanceName));

var db = smoServer.Databases[dbName];
if (db == null)
{
    db = new Microsoft.SqlServer.Management.Smo.Database(smoServer, dbName);
    db.Create();
}

restore.Devices.AddDevice(backupFileName, DeviceType.File);
restore.Database = dbName;
restore.FileNumber = 0;
restore.Action = RestoreActionType.Database;
restore.ReplaceDatabase = true;

var dbDataFile = db.FileGroups[0].Files[0];
restore.RelocateFiles.Add(new RelocateFile(dbDataFile.Name, dbDataFile.FileName));
var dbLogFile = db.LogFiles[0];
restore.RelocateFiles.Add(new RelocateFile(dbLogFile.Name, dbLogFile.FileName));

restore.SqlRestore(smoServer);

db.SetOnline();
smoServer.Refresh();
db.Refresh();

无论您以前手动还原了该Db,仅使用名称而不用数据手动创建了一个Db还是不进行任何操作-无论是从一台完全空白的机器开始,仅安装了Sql Server还是没有任何数据库的情况下,此代码都将起作用。 / p>

答案 12 :(得分:-1)

请更改.mdf文件路径。只需在任何驱动器中创建一个文件夹,即 - 在“D”驱动器中,只需创建一个带有自定义名称(dbase)的文件夹并指向新文件夹的路径,mssql将自动创建文件。

“C:\ PROGRAM FILES \ MICROSOFT SQL SERVER \ MSSQL.1 \ MSSQL \ DATA \ MYDB_ABC.MDF” 至 “d:\质数据库\ MYDB_ABC.MDF”