Sql server 还原数据库备份时出错
还原使用以前版本(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计算机,我的数据库文件位于以下位置: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
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();
无论您以前是否手动还原过此数据库,是否仅使用名称而不使用数据手动创建了一个数据库,或者是否未执行任何操作,此代码都可以使用