Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 还原数据库备份时出错_Sql Server_Database_Exception Handling_Restore_Sql Server 2012 - Fatal编程技术网

Sql server 还原数据库备份时出错

Sql server 还原数据库备份时出错,sql-server,database,exception-handling,restore,sql-server-2012,Sql Server,Database,Exception Handling,Restore,Sql Server 2012,还原使用以前版本(SQL Server 2008)进行的备份时,使用SQL Server 2012时出错。实际上,我有几个相同数据库的备份文件(在过去的不同时间拍摄)。最新的恢复没有任何问题;但是,其中一个给出了以下错误: System.Data.SqlClient.SqlError:文件的目录查找 “C:\PROGRAM FILES\MICROSOFT SQL 服务器\MSSQL.1\MSSQL\DATA\MYDB_ABC.MDF“操作失败 系统错误3(系统找不到指定的路径。)。 (Micro

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

System.Data.SqlClient.SqlError:文件的目录查找 “C:\PROGRAM FILES\MICROSOFT SQL 服务器\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

听起来备份是在路径与您的路径不匹配的机器上进行的。尝试使用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';

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


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

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

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

日志文件也是如此。

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

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

我也遇到了同样的问题,这在没有任何C代码的情况下修复了它:

使用[master]
ALTER数据库[MyDb]
将单用户设置为立即回滚
还原数据库[MyDb]
FROM DISK=N'D:\backups\mydb.bak'
如果FILE=1,
将N'MyDb'移动到N'c:\valid\u data\u path\MyDb.mdf',
将N'MyDb\u log'移动到N'\valid\u log\u path\MyDb.ldf',
名词负载,
代替
统计数据=5
ALTER DATABASE[MyDb]设置多用户
去

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

此选项中存在一些版本问题。您可以通过另外两种方法将数据库迁移到2012:-

1) 使数据库脱机>将.mdf和.ldf文件复制到目标服务器数据文件夹并附加数据库。请参阅:-

2) 使用schema&Data创建整个数据库的脚本,并在目标服务器上运行它(非常慢的过程需要时间)。请参阅:-
尝试重新启动SQL服务。为我工作

如前所述,恢复mdf和ldf文件的新旧路径不匹配的备份可能会导致此错误。这里已经有几个很好的例子说明了如何使用SQL来处理这个问题,但是在我意识到我需要在“MOVE”语句的from部分包含“.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建议我需要使用带移动的
选项,而我已经这样做了。

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


为了防止这对直接使用Powershell(使用库)的人有用,在这种特殊情况下,还存在辅助数据文件。我通过终止所有打开的进程,然后执行恢复,对脚本进行了一些增强

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

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

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 

当您使用一个MSSQL Studio进行备份(连接到旧服务器)和恢复(连接到新服务器)时,通常会发生这种情况。只需确保您在正确的服务器上执行恢复即可。在UI或dou的左窗格中检查服务器名称和IP。如果使用C#执行此操作,并且物理路径不相同,则需要使用重定位文件,这里也提到了一个答案

在大多数情况下,假设以下代码有效:

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

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

  • 此外,只有在第一次恢复时才需要执行以下操作。一旦单次成功还原,将在Sql Server中为您设置以下文件映射。但是,第一次——将bak文件恢复为空白数据库——你基本上必须说,“是的,在默认的本地位置使用数据库文件,而不是惊慌失措”,你需要告诉它保持在同一位置,奇怪的是,告诉它重新定位:

    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();
    
    无论您以前是否手动还原过此数据库,是否仅使用名称而不使用数据手动创建了一个数据库,或者是否未执行任何操作,此代码都可以使用