您的位置:首页 > 数据库

如何处理SQLServer数据库损坏

2017-12-17 18:13 579 查看

前言

作为数据库技术顾问,我每年有会处理超过10起以上客户数据库损坏的的案例。在论坛每年也会有几十次以上发帖咨询相关问题.。数据库损坏的危害是极其严重的,但是偏偏又是经常出现,这是为什么呢?因为大多数数据库缺乏专业的人员管理,没有做好定期的巡检,真正发现问题的时候已经是灾难性的 。那么如果我们不幸的那遇到这些类似的情况,我们应该怎么做呢?

真实案例1

以下是近期遇到的处理的一个真实案例。一个名为DB的数据库于2017年12月14日晚9点半左右状态变为可疑,12月15日早9点半对SQL 数据库服务进行了重启。重启后故障数据库状态变为正在恢复,即SSMS中数据库列表显示DB正在恢复)。大概90分钟后DB_Center状态恢复正常,此时数据库中绝大部分表均可以正常访问,大部分业务恢复正常。下午3点左右发现数据库中有一个名为table1的表出现死锁,运行Sp_who命令后发现blocking_session_id为-3。

经过排查日志发现在SQL服务重启后,会出现如下错误:





我们应该怎么做

不要惊慌

不要分离数据库

不要重新启动SQL

不要直接运行修复。

运行一个完整性检查
之后,进行根本原因分析

保持冷静

处理任何形式的数据库损坏时最重要的是保持冷静。任何决策或采取的行动都应仔细考虑,并仔细考虑所有因素考虑。错误的决策可能会让情况变得更糟。

不要分离数据库

  在绝大多数情况下,如果SQL检测到数据库中的损坏,则意味着DB中确实存在一些损坏的页面。通过分离和重新附加数据库,备份和恢复已经损坏数据库,重新启动SQL服务或重新启动计算机不会使损坏消失。如果数据库中存在损坏,在附加数据库的时候,SQL Server 会检测到数据库的损坏,导致附加失败。虽然有某些办法将数据库强制附加上去,但是最好不要将数据库分离出来

不要重新启动SQL

与分离类似,如果存在数据库损坏,重新启动SQL服务将不会修复损坏。与分离数据库一样,重新启动服务可能会使事情变得更糟。如果SQL Server在对数据库执行重新启动恢复时遇到损坏,则该数据库将被标记为可疑,使得任何必要的修复都难以实现。

不要直接运行修复

有我们可能会希望,只要运行一个修复选项(也许是允许数据丢失),就可以把数据库损坏修复好。但是在很多情况下是,即使允许数据库丢失的修复也不能把损坏的数据库修复好,而且会导致数据丢失,在大多数情况下,修理是修复损坏的最后手段。只有在没有其他选择是可能的时候才应该做,而不是做的第一件事。

运行一个完整性检查

要确定修复损坏的方法,必须知道确切损坏的细节。获取此信息的唯一方法是使用All_ErrorMsgs选项运行CheckDB(在2005 SP3上,这是CheckDB中的默认选项,不需要指定,它需要在SQL 2008中指定)。此外,No_Infomsgs选项将删除有关表中行数和页数的所有信息,这在处理损坏时是不必要的。

CheckDB在大型数据库上可能需要相当长的一段时间,但是有必要让它运行完成。如果不知道数据库中的所有问题,就不应该考虑修复策略

根本原因
一旦损坏得到解决,工作还没有结束。如果找不到损坏的根源,可能会再次发生。通常腐败的主要原因是IO子系统的问题。其他可能的原因是行为不当的过滤器驱动程序(如防病毒),人为干预或SQL中的错误。

进一步排查问题

解决数据库损坏问题完全取决于CHECKDB的结果,下面会列举一些常见问题场景。按照从损坏的严重程度由低到高的顺序。

分配空间元数据不正确

对于索引 ID 为 0、分区 ID 为 81582083080192、分配单元 ID 为 81582083080192 (类型为 In-row data)的对象 "GL_accass",计数 In-row data RSVD page 不正确。请运行 DBCC UPDATEUSAGE。
这不是一个严重的问题,。 正如消息所提示,在有问题的数据库上运行DBCC UPDATEUSAGE,警告将消失。 这在从SQL 2000升级上来的数据库上是很常见的. 不会发生在SQL 2005/2008中创建的数据库上。

损坏只发生在非聚集索引

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息