我正在使用数据库应用程序来还原带有事务日志的数据库。我正在使用SQL Server管理对象(SMO)库。
此应用程序的要求使其得以实现,因此我必须在单独的进程中还原数据库备份文件及其事务日志。我可以毫不费力地恢复备份文件,但是在恢复事务日志时遇到了一个问题:
public void RestoreTransactionLogs(Server srv, DirectoryInfo filePath, DatabaseType dbType)
{
Restore res = new Restore()
{
Database = dbType.ToString(),
Action = RestoreActionType.Log,
ReplaceDatabase = false
};
FileInfo[] files = filePath.Parent.GetFiles("*.trn");
foreach (FileInfo f in files)
{
res.Devices.AddDevice(f.FullName, DeviceType.File);
}
try
{
res.SqlRestore(srv);
}
catch (SmoException ex)
{
Log.Fatal("An SMO Exception has occurred when restoring the database: " + dbType.ToString() + ": " + ex.Message);
throw ex;
}
catch (Exception ex)
{
Log.Fatal("An exception has occurred when restoring the database: " + dbType.ToString() + ": " + ex.Message);
throw ex;
}
}
使用测试备份文件和20个事务日志,我遇到以下错误:
SmoException:System.Data.SqlClient.SqlError:加载的媒体 “ D:\ Test文件夹\ testDatabase \ log_00001.trn”的格式设置为支持 1个媒体家庭,但预计20个媒体家庭 备份设备规范。
我觉得我没有将事务日志正确地添加到我的设备集合中,或者应该以其他方式添加它们,但是不确定在哪里检查。来自MSDN的用于事务日志的文档很稀少,而且我在网上找不到很多。谢谢!
答案 0 :(得分:0)
我认为您的问题是您不能仅还原事务日志。您必须先从完整备份开始,然后再应用事务日志。这必须在db处于无恢复状态时发生,因此在完全备份还原和事务日志还原之间不会对db进行其他任何更改。另外,请记住,您必须按照处理顺序来应用事务日志。
这是我根据此处的doco示例进行的工作:
using (SqlConnection connection = new SqlConnection(connectionString))
{
var server = new Server(new ServerConnection(connection));
Database targetDb = server.Databases["TargetDbName"];
// Make sure your user has ALTER ANY CONNECTION rights for this
// not needed if you can be sure db is not in use
server.KillAllProcesses(targetDb.Name);
targetDb.SetOffline();
Restore restoreDB = new Restore();
restoreDB.Database = targetDb.Name;
restoreDB.Action = RestoreActionType.Database;
restoreDB.ReplaceDatabase = true;
// Restore the full backup first
var fullBackupDevice = new BackupDeviceItem("fullBackupFile.bak", DeviceType.File);
restoreDB.Devices.Add(fullBackupDevice);
restoreDB.NoRecovery = true;
restoreDB.SqlRestore(server);
restoreDB.Devices.Remove(fullBackupDevice);
// Get the first taken transaction log file
var firstTransactionBackupDevice = new BackupDeviceItem("firstTrnFile.trn", DeviceType.File);
restoreDB.Devices.Add(firstTransactionBackupDevice);
restoreDB.SqlRestore(server);
restoreDB.Devices.Remove(firstTransactionBackupDevice);
// Get the second taken transaction log file
var secondTransactionBackupDevice = new BackupDeviceItem("secondTrnFile.trn", DeviceType.File);
restoreDB.Devices.Add(secondTransactionBackupDevice);
// You have to set this flag to false before the last file you will restore
// to return the db to the normal state
restoreDB.NoRecovery = false;
restoreDB.SqlRestore(server);
restoreDB.Devices.Remove(secondTransactionBackupDevice);
targetDb.SetOnline();
server.Refresh();
}
我知道您的问题有点老了,您可能已经找到了解决方案,但是希望对其他人有所帮助。
答案 1 :(得分:-1)
您好,您可以在sql服务器中尝试以下脚本。不要更改目录文件路径。还要对“有恢复”和“无恢复”进行研究。
RESTORE DATABASE [DW] FROM DISK = 'G:\MSSQL\Data\FullBackups\db.bak' WITH NORECOVERY
Go
RESTORE DATABASE [DW] FROM DISK = 'G:\MSSQL\Data\DifferentialBackups\db.bak' WITH NORECOVERY
--repeat how many ever times if multiple based on time DB crashed.
GO
RESTORE DATABASE [DW] FROM DISK = 'G:\MSSQL\Data\TransactionLogs\db.bak' WITH NORECOVERY
--Final T-Log to exact point in time recovery.
RESTORE DATABASE [DW] FROM DISK = 'G:\MSSQL\Data\TransactionLogs\db.bak' WITH RECOVERY