gpt4 book ai didi

c# - 当 .bak 文件中有多个备份点时使用 SMO 还原类

转载 作者:太空狗 更新时间:2023-10-29 21:39:12 28 4
gpt4 key购买 nike

我正在尝试使用 SMO 编写一个简单的实用程序来备份/恢复数据库。当备份文件中只有一个时间点时,这种方法非常有效。然而,当有一个备份文件定义了多个备份点(不是备份集)时,SMO 总是选择最早的,而 SSMS 总是选择最新的。

这会导致数据恢复不正确,我想弄清楚是否可以设置一个属性来强制 Restore 类始终使用最新的备份点。

我已经尝试设置 Restore.ToPointInTime,但由于数据库的恢复模型很简单,所以无法正常工作。

我找到了一篇描述如何选择恢复时间的 MSDN 文章,其中包括将数据库设置为完全恢复模式:

http://technet.microsoft.com/en-us/library/ms179451(v=sql.105).aspx

使用 SMO 时是否有必要这样做,有没有办法使用纯 SMO(无 C# sql 命令)来做到这一点?我使用了 Restore.ReadBackupHeaders,从中我能够及时提取可用的备份点,但无法将其设置为在任何地方恢复。

编辑:

这是我正在使用的代码,包括最近尝试通过 smo 设置数据库恢复模型的更改:

    public void RestoreDatabase(string databaseName, string backupPath)
{
var server = new Server(GetServerConnection());

//If the database doesn't exist, create it so that we have something
//to overwrite.
if (!server.Databases.Contains(databaseName))
{
var database = new Database(server, databaseName);
database.Create();
}

var targetDatabase = server.Databases[databaseName];
targetDatabase.RecoveryModel = RecoveryModel.Full;
targetDatabase.Alter();

Restore restore = new Restore();

var backupDeviceItem = new BackupDeviceItem(backupPath, DeviceType.File);
restore.Devices.Add(backupDeviceItem);
restore.Database = databaseName;
restore.ReplaceDatabase = true;
restore.Action = RestoreActionType.Database;

var fileList = restore.ReadFileList(server);

var dataFile = new RelocateFile();
string mdf = fileList.Rows[0][1].ToString();
dataFile.LogicalFileName = fileList.Rows[0][0].ToString();
dataFile.PhysicalFileName = server.Databases[databaseName].FileGroups[0].Files[0].FileName;

var logFile = new RelocateFile();
string ldf = fileList.Rows[1][1].ToString();
logFile.LogicalFileName = fileList.Rows[1][0].ToString();
logFile.PhysicalFileName = server.Databases[databaseName].LogFiles[0].FileName;

restore.RelocateFiles.Add(dataFile);
restore.RelocateFiles.Add(logFile);

var backupHeaderInfo = GetBackupHeaderInformation(restore, server);
var latestBackupDate = backupHeaderInfo.Max(backupInfo => backupInfo.BackupStartDate);

restore.ToPointInTime = latestBackupDate.ToString();

server.KillAllProcesses(databaseName);

restore.SqlRestore(server);
}

看起来这应该可以解决问题,但是行

targetDatabase.RecoveryModel = RecoveryModel.Full

似乎没有做任何改变恢复模型的事情,导致我仍然得到以下异常:

The STOPAT option is not supported for databases that use the SIMPLE recovery model. RESTORE DATABASE is terminating abnormally.

编辑 2:

我添加了行

targetDatabase.Alter();

它解决了不更新的问题。然而,它现在恢复但使数据库处于恢复模式,因此无法查询。

编辑 3:

我通过将 Restore.FileNumber 属性设置为 BackupHeaders 中位置的最大值来使代码工作,这似乎可以解决问题,但我仍然不确定为什么备份文件有多个备份 header ,但是只有一个备份集。

工作代码如下。

    public void RestoreDatabase(string databaseName, string backupPath)
{
var server = new Server(GetServerConnection());

//If the database doesn't exist, create it so that we have something
//to overwrite.
if (!server.Databases.Contains(databaseName))
{
var database = new Database(server, databaseName);
database.Create();
}

var targetDatabase = server.Databases[databaseName];
targetDatabase.RecoveryModel = RecoveryModel.Full;
targetDatabase.Alter();

Restore restore = new Restore();

var backupDeviceItem = new BackupDeviceItem(backupPath, DeviceType.File);
restore.Devices.Add(backupDeviceItem);
restore.Database = databaseName;
restore.ReplaceDatabase = true;
restore.NoRecovery = false;
restore.Action = RestoreActionType.Database;

var fileList = restore.ReadFileList(server);

var dataFile = new RelocateFile();
dataFile.LogicalFileName = fileList.Rows[0][0].ToString();
dataFile.PhysicalFileName = server.Databases[databaseName].FileGroups[0].Files[0].FileName;

var logFile = new RelocateFile();
logFile.LogicalFileName = fileList.Rows[1][0].ToString();
logFile.PhysicalFileName = server.Databases[databaseName].LogFiles[0].FileName;

restore.RelocateFiles.Add(dataFile);
restore.RelocateFiles.Add(logFile);

var backupHeaderInfo = GetBackupHeaderInformation(restore, server);
restore.FileNumber = backupHeaderInfo.Where(backupInfo => backupInfo.BackupType == BackupType.Database).Max(backupInfo => backupInfo.Position);

server.KillAllProcesses(databaseName);

restore.SqlRestore(server);

targetDatabase.SetOnline();
}

最佳答案

尽管您说您没有多个备份集,但我认为您有。来自备份集表的文档:

A backup set contains the backup from a single, successful backup operation.

因此,如果您在单个备份文件中有“多个还原点”,那么您就有多个备份集。通过查询 msdb 中的 dbo.backupset 表来验证这一点

撇开迂腐不谈,我认为您正在寻找 Restore 对象的 FileNumber 属性。这对应于 FILE = n T-SQL 恢复命令中的备份集选项。为了获得最后一个,只需从 ReadBackupHeaders 调用中拉出最后一行。

要自行测试,请完成通过 SSMS 执行恢复的 Action ,然后不要点击“确定”,而是点击顶部附近的“脚本”按钮。我怀疑你会看到 FILE = <some number>在某处。

关于c# - 当 .bak 文件中有多个备份点时使用 SMO 还原类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25254269/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com