SQL Server数据库损坏、检测以及简单的修复办法 数据库损坏

数据库损坏(SQL Server数据库损坏、检测和简单修复)
在一个理想的世界里 , 不会有任何数据库损坏 , 就像我们在日常生活中不包括一些严重的突发情况一样 。这样的事情一旦发生 , 肯定会对我们的生活产生非常重大的影响 , SQL Server也是如此 。也许你已经几年没有在一个数据库里看到过这样的情况了 , 但是一旦遇到这样的情况 , 往往伴随着数据丢失 , 宕机 , 严重的问题甚至你自己的职业生涯都会受到影响 。所以对于这种情况 , 我们需要了解数据库损坏的知识 , 以便提前做好准备 , 事后应对 。本文将讨论数据库损坏的原因、现象、前后处理方法以及简单的修复方法 。
为什么数据库会损坏?在了解数据库损坏之前 , 我们应该先了解SQL Server如何将数据保存到数据文件(MDF、NDF等 。).无论是更新数据还是插入数据 , 数据首先都需要驻留在内存中的缓冲池中 , 然后通过检查点、懒写器等进程将内存中的数据持久化到磁盘 。在此过程中 , 脏页数据从内存写入持久IO子系统 。在此期间 , 根据IO子系统 , 数据可能会通过这些层:
Windows(写数据时必须调用WINDOWS API)
Windows底层的中间层(杀毒软件、磁盘加密系统)
网卡、路由器、交换机、光焊、网线等 。(如果IO子系统没有直接连接)
SAN控制器(如果使用SAN)
RAID控制器(IO子系统已被RAID)
或者诸如磁盘SSD的永久存储器 。
因此 , 当一个数据页被写入持久存储时 , 它可能会经过上面列表中的几项 。在上述过程中 , 硬件环境会受到多方面的影响 , 比如电压是否稳定、电源是否故障、温度高低、湿度等 。至于软件 , 可能会有bug , 因为软件是人写的 , 可能会导致数据页面传输过程出错 。
此外 , 影响磁盘的因素还包括电压稳定性、灰尘等因素 , 这些因素也可能导致磁盘磁道不良或整体损坏 。
上述所有因素都可以归因于IO子系统 。所以大部分数据损坏都是IO子系统造成的 , 内存芯片也有非常非常小的概率会造成数据页损坏 , 但这部分情况很小 , 不在本文讨论范围内 。
上面提到的数据损坏的原因都是天灾 , 也有一些是人祸 。例如 , 当数据文件被编辑器等手动编辑 , 并且数据库中存在需要重做和撤消的事务时(即没有干净关闭) , 日志文件被删除(这通常会导致数据库查询) 。
发现数据库损坏 。在我们了解了数据库损坏的可能原因之后 , 让我们看看SQL Server是如何监视数据库页损坏的 。
在SQL Server的数据库级别 , 可以用三个选项设置页面保护类型:None、CheckSum、Torn_Page_Detection , 如图1所示:
图一 。页面保护的三个选项
关于这三个选项 , 首先请不要忽略任何一个 。请不要在任何情况下选择此选项 。此选项意味着SQL Server不保护页面 。
其次 , 撕裂_页面_检测 。在SQL Server中 , 数据的最小单位是页 , 每页8K , 但对应的磁盘上往往有16个512字节的扇区 。如果在写持久存储的过程中只写了一半的页面 , 这就叫做TORN_PAGE_DETECTION 。SQL Server以每个扇区512字节的前两位作为元数据 , 总共16个扇区有32位和4字节的元数据(在页头标记为m_tornBits) 。通过该元数据 , 可以检测部分写入的字符串的存在 , 但是这种类型的页面验证不能检测页面中的写入错误 。因此 , 在SQL Server 2005及以上版本中 , 应尽可能选择校验和 。
在SQL Server 2005及以上版本中引入了CheckSum , 可以理解为校验和 。当一个数据页被写入持久存储时 , 会根据页值计算出一个4字节的校验和 , 并存储在页头中(页头中相同的标识符为:m_tornBits) , 它会和同一页中的数据一起存储在数据库中 。当数据从IO子系统读入内存时 , SQL Server将根据页中的值重新计算校验和 , 并将重新计算的校验和与存储在页头中的校验和进行比较 。如果比较失败 , SQL Server将认为该页已损坏 。
从校验和的过程可以看出 , 只有当页面写入SQL Server时 , 才会计算校验和 。因此 , 如果只更改数据库选项 , 页眉中的元数据将不会相应地更改 。

推荐阅读