MS SQL Server 2008 使用 SMO 还原数据库会损坏资源数据库

本文关键字:数据库 损坏 资源 还原 SMO SQL Server 2008 使用 MS | 更新日期: 2023-09-27 18:34:03

我目前在一个数据库实例中遇到了一个非常奇怪的问题。我编写了一个小型应用程序,用于从一个 MS SQL Server 2008 实例备份一组数据库,并在第二个实例上的现有数据库之上还原同一组数据库。这两个实例都在 Windows Server 2008R2 计算机上运行。备份和还原是使用 MS SQL Server 管理对象 (SMO( 完成的,该对象内置于简单的 C# Windows 窗体中。

在第二个实例上还原数据库后,我遇到了几个问题:

  • 右键单击数据库并选择"属性"会给我以下错误消息|-> 无法显示请求的对话框 (SqlMgmt(|-> 执行事务处理 SQL 语句或批处理时发生异常 |-> 由于数据移动,无法使用 NOLOCK 继续扫描。(Microsoft SQL Server,错误: 601(
  • 我无法打开活动监视器(相同的错误消息(
  • SQL 错误
  • 日志报告资源数据库已损坏("SQL Server 检测到基于逻辑一致性的 I/O 错误:保护选项无效。它发生在阅读页面期间...在数据库 ID 中...在偏移...在文件中..."(
  • SELECT SERVERPROPERTY('ResourceVersion'( 命令给出一个版本号
  • 从另一个 SQL Server 复制资源数据库的 MDF 和 LDF 文件(并重新启动服务(解决了问题

现在我知道资源数据库应该是只读的,并且在硬件问题之外,它不可能损坏,这真的让我想知道,我在哪里搞砸了?为什么替换资源数据库可以解决我的问题?

有没有人遇到过同样的问题?

更新:使用以下命令执行备份:

Backup backup = new Backup();
backup.Action = BackupActionType.Database;
backup.Database = databaseName;
backup.CopyOnly = true;
backup.Checksum = true;
backup.BackupSetDescription = "Full backup of " + databaseName;
backup.BackupSetName = databaseName + " Backup";
backup.Initialize = true;
string backupFilePath = backupLocation + "''" + databaseName + ".bak";
backup.Devices.AddDevice(backupFilePath, DeviceType.File);
Microsoft.SqlServer.Management.Smo.Server smoServer = new Server(connectionString);
smoServer.ConnectionContext.StatementTimeout = 0;
smoServer.ConnectionContext.AutoDisconnectMode = AutoDisconnectMode.NoAutoDisconnect;
smoServer.ConnectionContext.Connect();
backup.SqlBackup(smoServer);
smoServer.ConnectionContext.Disconnect();

..并按如下方式验证:

Restore restore = new Restore();
string backupFilePath = backupLocation + "''" + databaseName + ".bak";
Microsoft.SqlServer.Management.Smo.Server smoServer = new Server(connectionString);
BackupDeviceItem deviceItem = new BackupDeviceItem(backupFilePath, DeviceType.File);
restore.Devices.Add(deviceItem);
bool verified = restore.SqlVerify(smoServer);

还原通过以下方式执行:

Microsoft.SqlServer.Management.Smo.Server smoServer = new Server(connectionString);
smoServer.ConnectionContext.StatementTimeout = 0;
smoServer.ConnectionContext.AutoDisconnectMode = AutoDisconnectMode.NoAutoDisconnect;
smoServer.ConnectionContext.Connect();
Database db = smoServer.Databases[databaseName];
Restore restore = new Restore();
string backupFilePath = backupLocation + "''" + databaseName + ".bak";
BackupDeviceItem deviceItem = new BackupDeviceItem(backupFilePath, DeviceType.File);
restore.Devices.Add(deviceItem);
restore.Database = databaseName;
restore.Action = RestoreActionType.Database;
restore.ReplaceDatabase = true;
restore.SqlRestore(smoServer);
db = smoServer.Databases[databaseName];
db.SetOnline();
smoServer.Refresh();
db.Refresh();
Restore rest = new Restore();
rest.Devices.AddDevice(backupFilePath, DeviceType.File);
bool verifySuccessful = rest.SqlVerify(smoServer);
smoServer.ConnectionContext.Disconnect();

我知道一旦备份或还原完成,连接实际上应该断开,并且实际上确实正确连接和断开连接,这个手动连接和断开连接的最新版本是一个实验,用于检查最终结果是否有任何差异。没有。

备份和还原都在后台工作线程中执行,在内部try...捕获循环,并且不会引发异常。

我相信这些参数是不言自明的,但如果有什么不清楚的地方,我很乐意澄清。

更新 2:经过更彻底的一轮测试,我无法重现资源数据库损坏问题。因此,当我第一次尝试恢复时,我将此归咎于行星对齐。感谢杰罗恩的帮助和提示!

MS SQL Server 2008 使用 SMO 还原数据库会损坏资源数据库

没有理由假设您的备份/还原与数据库故障有任何关系。遇到损坏时,请执行通常的操作:运行 DBCC CHECKDB ,检查硬件是否存在错误,查看是否有适用于您的版本的累积更新可以解决损坏问题。如果可以通过还原数据库来一致地重现错误,即使在具有完全相同版本的 SQL Server 的另一台计算机上也是如此,则可能已发现 MS 感兴趣的错误。否则,我会仔细查看硬件。

替换资源数据库修复它的事实并不意味着您已经找到并修复了根本问题,只是它不再损坏。这仍然没有告诉你任何关于腐败的原因。

为了完整起见:除了手动编辑数据库文件(通过DBCC PAGE或只是通过在SQL Server外部写入数据库文件(之外,您所做的一切都不是数据库损坏的合法原因,因此您绝对没有"搞砸"。