24

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

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.

4

14 回答 14

39

听起来备份是在路径与您的路径不匹配的机器上进行的。尝试使用 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';
于 2012-05-24T16:16:03.040 回答
15

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

选中“将所有文件重定位到文件夹”

于 2018-01-18T09:56:29.853 回答
10

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

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

于 2012-05-24T16:16:10.430 回答
7

我已经设法从代码中做到了这一点。这还不够

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));
      }                  
   }
}

日志文件也一样。

于 2012-05-25T09:17:09.470 回答
6

我遇到了同样的问题,这在没有任何 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
于 2014-10-20T06:33:39.883 回答
3

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

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在我已经这样做时需要使用该选项。

于 2017-05-11T12:38:01.787 回答
0

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

于 2016-01-04T14:48:08.453 回答
0

这有一些版本问题。您可以通过另外 2 种方法将数据库迁移到 2012:-

1) 使数据库脱机 > 将 .mdf 和 .ldf 文件复制到目标服务器数据文件夹并附加数据库。参考这个:- https://dba.stackexchange.com/questions/30440/how-do-i-attach-a-database-in-sql-server

2)使用模式和数据创建整个数据库的脚本并在目标服务器上运行(非常慢的过程需要时间)。请参考:- 在 SQL Server Management Studio 中生成脚本

于 2015-08-26T20:05:57.610 回答
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
于 2018-01-18T20:57:40.353 回答
0

请尝试取消选中“还原数据库”对话框的“选项”页面上的“尾日志备份”选项

于 2015-07-29T00:22:51.280 回答
0

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

于 2019-04-24T11:24:34.230 回答
0

如果您使用 C# 执行此操作,并且物理路径不相同,则需要使用 RelocateFiles,正如此处还提到的一个答案。

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

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

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

此外,以下内容仅在第一次还原时是必需的。一旦一个成功的恢复发生,下面的文件映射已经在 Sql Server 中为你设置好了。但是,第一次 - 将 bak 文件恢复到空白数据库 - 你基本上必须说,“是的,在默认的本地位置使用 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、仅使用名称但没有数据手动创建了一个,或者什么都不做,此代码都可以使用 - 从一台完全空白的机器开始,只安装了 Sql Server,没有任何数据库。

于 2019-12-16T14:18:01.950 回答
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 
于 2019-03-05T17:26:29.913 回答
-1

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

“C:\PROGRAM FILES\MICROSOFT SQL SERVER\MSSQL.1\MSSQL\DATA\MYDB_ABC.MDF”到“D:\dbase\MYDB_ABC.MDF”

于 2013-10-03T06:06:06.190 回答