【问题标题】:Cannot abort the Restore DB无法中止还原数据库
【发布时间】:2012-02-26 09:57:43
【问题描述】:

我想为用户提供取消按钮 - 以中止正在进行的恢复。为此,在Restore.PercentComplete 事件处理程序中,我检查用户是否单击了取消按钮并调用Restore.Abort()。但这无济于事:

SMO 抛出异常:

服务器“MICHAEL7”的恢复失败。
执行 Transact-SQL 语句或批处理时发生异常。
堆栈跟踪:在 Microsoft.SqlServer.Management.Smo.Restore.SqlRestore(Server srv)

数据库永远处于“恢复”模式。以下是相关代码:

using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;

private volatile bool _CancelRestore = false;
private Restore _RestoreDB;
private Server _myServer;
private Database _currentDatabase;

// user hits Cancel buttton
public void CancelRestore()
{
    _CancelRestore = true;
}

// Restore.PercentComplete event handler
private static void CompletionStatusInPercent(object sender, PercentCompleteEventArgs args) 
{
    if (_CancelRestore)
    {
        _RestoreDB.Abort();

          // Disable the kills to let some time to Abort()

        // Stop all processes running on the _currentDatabase database
        // _myServer.KillAllProcesses(_currentDatabase.Name);

        // Stop the _currentDatabase database
        // NOTE: it is a temp name DB: I do not restore over my application DB!
        // _myServer.KillDatabase(_currentDatabase.Name);
    }
    else
    {
        Console.Clear();
        Console.WriteLine("Percent completed: {0}%.", args.Percent);
    }
}

备份/恢复功能是在本文的帮助下实现的:SQL Server 2005 Database Backup and Restore using C# and .NET 2.0

谢谢。

【问题讨论】:

  • 放一个断点,看看CompletionStatusInPercent是否经常被命中(应该是),还添加一个volatile关键字到_CancelRestore这应该禁用布尔的任何CPU缓存并强制线程检查 bool 的实际值(尽管不能保证)。
  • 嗨@oleksii。感谢挥发性。断点在那里并且可以正常访问。我猜问题出在某处的 SMO 中。我需要一个备份/恢复中止的工作示例。
  • 注释掉杀死的东西!你没有给它时间重新组合!
  • 嗨@Tony,把东西干掉 - 完成。还是一样的例外。
  • 如果您像取消还原一样手动执行此操作,会发生什么?不能说是我自己做的,这种事情让我很紧张,更有可能让它完成然后恢复之前的备份以撤消“不正确”的恢复。

标签: c# sql-server database smo


【解决方案1】:

我知道这是一个老问题,但我遇到了同样的问题,我找到了适合我的解决方案。

我使用以下内容而不是 KillDatabase:

sqlRestore.Abort();
sqlRestore.Wait(); //This will wait until the restore operation is canceled
Database db = _server.Database(databaseName);
if (db != null)
    db.Drop(); // This will drop the "half" restored Database

应该说,我正在使用 SqlRestoreAsync。

KillDatabase() 将终止所有连接,因此 KillAllProcesses() 在这里已过时。

她是我的完整代码:

public async Task<bool> Restore(string backupFile, string databaseName, IProgress<int> progress, CancellationToken ct)
{
    Restore sqlRestore = null;

    bool result = await Task.Run(() =>
    {
        try
        {
            var deviceItem = new BackupDeviceItem(backupFile, DeviceType.File);
            sqlRestore = new Restore
            {
                Action = RestoreActionType.Database,
                Database = databaseName,
                Partial = false,
                ReplaceDatabase = true,
                PercentCompleteNotification = 1
            };
            sqlRestore.PercentComplete += (s, e) => progress.Report(e.Percent);
            sqlRestore.Devices.Add(deviceItem);

            if (_server.Databases[databaseName] != null)
                _server.KillAllProcesses(databaseName);

            sqlRestore.SqlRestoreAsync(_server);

            while (sqlRestore.AsyncStatus.ExecutionStatus == ExecutionStatus.InProgress)
            {
                ct.ThrowIfCancellationRequested();
                Thread.Sleep(500);
            }

            if (sqlRestore.AsyncStatus.ExecutionStatus == ExecutionStatus.Succeeded)
            {
                Database db = _server.Databases[databaseName];
                if (db != null)
                    db.SetOnline();

                _server.Refresh();
                return true;
            }
            return false;
        }
        catch (OperationCanceledException)
        {
            sqlRestore.Abort();
            sqlRestore.Wait();
            Database db = _server.Databases[databaseName];
            if (db != null)
                db.Drop();
            return true;
        }
        catch (ConnectionFailureException)
        {
            return false;
        }
        catch (Exception ex)
        {
            _server.KillDatabase(databaseName);
            return false;
        }
    }, ct);
    return result;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    相关资源
    最近更新 更多