以编程方式从C#恢复ms-sql系统数据库

问题描述 投票:1回答:1

虽然从恢复“普通”数据库的角度来看处理程序化备份恢复有很多问题和答案,但对于像[master][msdb][model]这样的系统数据库来说,我遇到了很多不同的问题。我想知道是否有人有贡献,特别是对于[master],但所有这些似乎都会引起问题。现在,我已经在单用户模式(整个服务)中启动ms-sql以使用T3608标志恢复master数据库,但是当我尝试在其上运行RESTORE DATABASE查询时,这会破坏我与断开管道的连接信息。检查服务控制台services.msc显示数据库服务不再运行。

换句话说,运行此查询似乎会使sql-server崩溃而没有有用的消息结果。

我们来看一些示例代码。查询生成代码如下所示:

string query = "RESTORE DATABASE @dbName FROM DISK " + 
    "= @backupPath WITH FILE = @fileID, REPLACE, ";
if (dataFileName != "") {
    query += "MOVE @dataFileName TO @dataFileLocation, ";
}
if (logFileName != "") {
    query += "MOVE @logFileName TO @logFileLocation, ";
}
query += "STATS=1";
SqlCommand cmdData = new SqlCommand(query, conn);
cmdData.Parameters.AddWithValue("@dbName", databaseName);
cmdData.Parameters.AddWithValue("@backupPath", filePath);
cmdData.Parameters.AddWithValue("@fileID", fileIndex);
if (dataFileName != "") {
    cmdData.Parameters.AddWithValue("@dataFileName", dataFileName);
    cmdData.Parameters.AddWithValue("@dataFileLocation", mdfPath);
}
if (logFileName != "") {
    cmdData.Parameters.AddWithValue("@logFileName", logFileName);
    cmdData.Parameters.AddWithValue("@logFileLocation", ldfPath);
}
cmdData.ExecuteNonQuery();

所以这是一个最简单的例子。 FileIndex是一个包含备份文件索引的整数,此处未初始化的所有其他变量都是包含各种路径和名称的字符串。请注意,手动执行此类查询会产生预期结果(还原备份文件)。

事件日志使事情变得更加怪异。我观察到这个消息:

快照隔离或读取提交的快照在数据库“master”中不可用,因为SQL Server是使用一个或多个未记录的跟踪标志启动的,这些标记阻止启用数据库进行版本控制。以快照隔离启动的事务将失败,在读提交的快照下运行的查询将成功,但将返回基于锁定的已提交读取。

据推测它可能会抱怨T3608。事件日志还包含有关“成功恢复”的消息,但检查DATA文件夹的内容显示我的程序实际上并没有放回我手动删除的数据库文件,但似乎什么都不做呢?

此时我对sql server的奇怪行为感到很困惑。任何人都可以了解这可能发生的原因吗?

编辑:

通过更改流程进行的更多挖掘和实验表明,实际上还需要msdb和model数据库,否则SQL Server将无法正常启动。因此,所有三个都需要存在才能恢复它们,并且你只能恢复三个,我现在称之为特殊数据库的特殊,复杂,特定的方式,这些方式对于它们中的每一个都是不同的。

究竟是什么以及我如何不确定。互联网包含许多相互矛盾的建议,并没有一个文件化的程序直接起作用。

我发现ms-sql保存了一个特殊的文件夹“Template Data”。在这里有一堆特殊数据库的模板。我可以将这些模板复制到真正的DATA文件夹中,以便有一个正在运行的sql-server来恢复备份的特殊数据库。

但是:执行此操作:在还原非主特殊程序(msdb和model)期间,服务器仍会自行终止。实际上可能没有任何东西可以恢复。

进一步检查日志文件揭示了这两个有趣的错误:

在数据库'model'中重做记录操作期间,日志记录ID(32:151:1)发生错误。通常,特定故障先前在Windows事件日志服务中记录为错误。从完整备份还原数据库,或修复数据库。

在文件'E:\ backupdb \ MSSQL12.TBUINST \ MSSQL \ Template Data \ modellog.ldf'中的偏移量0000000000000000读取期间,操作系统将错误5(拒绝访问。)返回给SQL Server。 SQL Server错误日志和系统事件日志中的其他消息可能提供更多详细信息。这是严重的系统级错误情况,威胁数据库完整性,必须立即纠正。完成完整的数据库一致性检查(DBCC CHECKDB)。这个错误可能是由许多因素造成的;有关详细信息,请参阅SQL Server联机丛书。

为什么现在尝试阅读“模板数据”中的内容?是因为模板系统db或msdb db或model db包含refs到模板model / msdb / etc db的硬编码路径,而且我必须发出move命令?何时/如何在恢复过程中发出这些?

我也意识到这一点:假设我首先恢复'master'数据库,并且它包含其他特殊数据库的路径,为什么SQL Server现在在模板数据文件夹中搜索?毕竟,它在恢复master数据库时会重新启动,因此其中的路径现在应该是默认值。更不用说,在每一次恢复操作中,我明确指出.bak文件和新的.ldf.mdf文件的位置?这没有任何意义。

c# sql-server backup
1个回答
1
投票

主数据库还原完成后,SQL Server会自动停止。您需要在代码中处理结果连接错误,重新启动SQL Server,然后继续还原其他系统数据库。

© www.soinside.com 2019 - 2024. All rights reserved.