SQL Server 恢复挂起解决方案
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
在数据库的日常管理中,我们不可避免的会遇到,服务器突然断电(没有进行电源冗余),服务器崩溃或者 SQL Server 服务突然停掉,悲催的是日志文件也损毁了,SQL Server服务器起来之后,发现数据库处于“恢复挂起”模式;更悲哀的是该数据库没有备份或者备份已经比较久远;最最可悲的是,已经做好了丢失部分数据的准备,使用 DBCC CEHECKDB 的 REPAIR_ALLOW_DATA_LOSS 选项修复数据库后,数据库还是无法上线: 文件激活失败。物理文件名称'D:\data\archlog1.ldf'可能不正确。 无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。如果事务日志文件被手动删除或者由于硬件或环境问题而丢失,则可能出现此错误。 消息 1813,级别 16,状态 2,第 18 行 无法打开新数据库 'PerfStats'。CREATE DATABASE 中止。 本文将分享两种处理这种问题的方式,帮助您成功恢复数据库。 模拟环境
首先,在数据库 PerfStats 中创建 testObject 表,并插入所有对象数据。接下来我们运行插入脚本,使用多次 CROSS JOIN,以获得足够多的数据,赢得时间,让我们在关闭测试实例时,插入事务仍然在运行。这将使得数据库处于不一致状态,需要在数据库启动时,执行恢复。在另外一个 SSMS 窗口执行如下关闭 SQL Server 实例的脚本:
停服后,将PerfStats 的日志文件改名或者移到其他路径,重新启动SQL Server 服务,可以看到,PerfStats 数据库处于“恢复挂起”状态: 此时,我们仅有一个孤立的,不一致的数据库文件。 首先,让我们通过删除数据库来清除系统分类。此时,我们必须先离线数据库:
copy或者重命名数据文件,以备我们测试使用。然后通过删除数据库,来清除系统分类: DROP DATABASE PerfStats 使用 ATTACH_REBUILD_LOG 来重建日志文件:
文件激活失败。物理文件名称'D:\DB\PerfStats_log.ldf'可能不正确。 无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。如果事务日志文件被手动删除或者由于硬件或环境问题而丢失,则可能出现此错误。 消息 1813,级别 16,状态 2,第 7 行 无法打开新数据库 'PerfStats'。CREATE DATABASE 中止。 到此为止,我们很可能只有去找备份文件还原了(如果有的话),否则可能就是一场大灾难了。 本文接下来将介绍两种可以用来恢复数据库的方式,以帮助您度过劫难。第一种方式是使用 CREATE DATABASE 语句中非归档的的命令。如你所知,微软是不支持使用非归档的语句,因为使用这个语句一旦出了问题,他们是概不负责的。另一种方法更机智,不需要使用非归档功能。 方案一、未归档的ATTACH_FORCE_REBUILD_LOG命令 到目前为止,因为没有日志文件,我们使用 CREATE DATABASE…FOR ATTACH 语句恢复数据库会失败。同时,因为数据库中有打开的事务,我们也不能使用 ATTACH_REBUILD_LOG 命令。有一个未归档的命令 ATTACH_FORCE_REBUILD_LOG 命令,正如其名称所显示,强制 CREATE DATABASE…FOR ATTACH 语句恢复数据库,尽管其是孤立的、有打开事务的数据库。当然,也会创建一个新日志文件。
数据库虽然恢复正常,但数据表对象仍然无效: 使用最小数据丢失的方式,修复数据库:
看到,有380个一致性错误,仅仅修复两个。
最后虽然修复好了数据库,但数据库最后一次checkpoint点之后的所有数据将会丢失。 方案二、不使用未归档的功能附加损毁的SQL Server数据库 步骤一、创建新数据库
步骤二、离线新数据库
步骤三、将新数据库的文件路径指向我们的孤立的?mdf?文件,并且将日志文件指向一个不存在的文件
测试上线情况:
消息 5120,级别 16,状态 101,第 39 行 无法打开物理文件“D:\DB\PerfStats.mdf”。操作系统错误 5:“5(拒绝访问。)”。 文件激活失败。物理文件名称'D:\DB\PerfStats_log.ldf'可能不正确。 消息 5181,级别 16,状态 5,第 39 行 无法重新启动数据库“PerfStats_Repair”。将恢复到以前的状态。 消息 5069,级别 16,状态 1,第 39 行 ALTER DATABASE 语句失败。 无法打开物理文件“D:\DB\PerfStats.mdf”。操作系统错误 5:“5(拒绝访问。)”。这是因为在移动MDF 文件时,Authenticated Users 的权限改变了,需要为其添加“完全控制”权限,右击文件→属性→点选 Authenticated Users 用户→编辑→点选Authenticated Users→勾选下方“完全控制”右侧“允许”下的多选框→确定即可 重新运行ONLINE 脚本。即使您不是 SQL Server 专家,也能够猜测到,运行那个脚本会报错。但是,如果您看一看下图捕获到的错误信息,您将会发现,当SQL Server 无法找到事务日志文件时(我们之前的操作是改变系统目录,将其指向一个不存在的文件),会对日志文件进行重建。当然,重建日志文件失败,其错误信息和我们附加孤立的 *.mdf 文件相同,此时,和之前附件情况唯一不同的是,*.mdf 文件附加成功了,这离我们成功又进了一步。 文件激活失败。物理文件名称'D:\DB\PerfStats_log.ldf'可能不正确。 无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。如果事务日志文件被手动删除或者由于硬件或环境问题而丢失,则可能出现此错误。 消息 5181,级别 16,状态 5,第 39 行 无法重新启动数据库“PerfStats_Repair”。将恢复到以前的状态。 消息 5069,级别 16,状态 1,第 39 行 ALTER DATABASE 语句失败。 此时数据库 PerfStats_repair 数据库处于“恢复还原”状态。 步骤四、重建SQL Server 事务日志文件 现在,您会看到,重建 SQL Server 事务日志并不是非常复杂,但是,您必须接受将要丢失数据这一事实。事实上,只有在从备份恢复损坏的数据库这条路被断掉之后,您才能选择使用这种方式。例如,如果一个事务在更新索引,并且更新操作执行了一个页拆分,你可能丢失之前提交的事务,因为页拆分是要进行日志记录的,而这一记录会因为日志文件的丢失而消失。 下面是恢复数据库的脚本:
第一个DBCC 命令是将所有的输出展示在查询结果中,而不是记录在错误日志中。接下来两个脚本将数据库分别置于紧急模式和单用户模式,这是我们执行 DBCC CHECKDB 的 REPAIR_ALLOW_DATA_LOSS 选项的前提。最后一句脚本是将数据库恢复多用户模式。 下图框起来的部分说明错误日志已经重建了: 文件激活失败。物理文件名称'D:\DB\PerfStats_log.ldf'可能不正确。 无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。如果事务日志文件被手动删除或者由于硬件或环境问题而丢失,则可能出现此错误。 将禁用数据库 "PerfStats_Repair" 中的 Service Broker,因为数据库(316755B8-71DB-41B0-A4C5-1D076DB9EA0E)中的 Service Broker GUID 与 sys.databases (52C1EA48-8B63-446C-95AA-76D65C6DE5C5)中的不匹配。 警告: 数据库 'PerfStats_Repair' 的日志已重新生成。已失去事务的一致性。RESTORE 链已断开,服务器不再有以前的日志文件的上下文,因此您需要了解它们的内容。应运行 DBCC CHECKDB 验证物理一致性。数据库已置于 dbo-only 模式。在准备使数据库可用时,需要重置数据库选项,并删除所有多余的日志文件。 至此,数据库已经恢复完成。 写在最后,完成数据库备份策略必不可少,备份、备份,还是备份!!! 该文章在 2024/8/24 12:09:05 编辑过 |
关键字查询
相关文章
正在查询... |