我经常被专业人士问道:在SQL SERVER 2008 中CHECKDB仍然被推荐使用吗?从SQL 2005开始SQL计算校验和来避免物理页损坏。然而,以我的经验(从SQL SERVER 7.0开始),我却从未能清楚地说明CHECKDB不是必要的。

其他人有好的建议吗?

_____________________________________________
From: Robert Dorr
Sent:Friday, February 20, 2009 9:04 AM

     这个问题曾经被提到很多次。的确,增加的数据库页审计校验和(DATABASE PAGE AUDIT CHECKSUM)减少了一些需要执行CHECKDB的次数。历史记录也表明,从SQL SERVER 7.0起数据库引擎的性能得到了显著提升,从而进一步减少了这种必要性。

     但是,像检验和这样的功能只是保证写入磁盘的是什么,读取出来就是什么。它并不验证许多其它的数据完整性问题,而CHECKDB就是为此面设计。比如CHECKDB验证系统表的元数据,页链,索引排序等等。

     这个问题的答案就是:从SQL SERVER 7.0起,这种必要性已经减少。一个严密的恢复计划应当包括数据库全备和CHECKDB,用以保证此计划的各个方面都是可用的。例如:你有一个干净的数据 库,备份它,并用于恢复。因为在备份媒体迁移过程中发生了某些事情,它被损坏了。SQL2008中的校验和备份(Backup with CHECKSUM)能够有益于这种场景。有些供应商说:这个永远没有必要,数据库引擎能搞定所有事情。我觉得这种说法有点片面。

例如:

  • 我曾处理过一个磁带驱动器不一致的案例。能够成功备份到磁带却不能读取它用于还原。除非执行还原操作,否则数据库引擎不会意识到硬件错误。这个客户损失了他的生产服务器并不能用恢复来还原。为此在一个磁带恢复公司身上花了$100,000.

  • 我曾经研究内存和ECC故障率。根据研究,内存传输中单独的位改变会导致数据损坏。这就是为什么SQL SERVER 2005对缓存池(Buffer Pool)增加了恒量页扫描(Constant Page Scanning)。当页在内存中时,恒量页扫描技术对校验和取样,用以确保只读页不会因为这样的错误而改变。这个技术用益于数据稳定,但是不能捕获所有 的事情。所以还是可能发生ECC故障,缓存池中的页可能被改变并成功计算校验和写入磁盘。我曾经处理过一个案例就是这个问题:一个数据值中间的一个位被改 变。这个列碰巧是一个被外键引用的主键。所以主键值是9,可能会被改变成19。因为这个重复的值19,导致了违反了主键约束,而外键引用的值9也不存在 了。这个数据的改变不是受事务影响而发生的,只是页中任何一个值的改变都会导致。这个数据库配置了日志传送,而备机不会显示此错误,结果把“水搞得更 混”。因为不是SQL SERVER直接导致主键值改变的,所以数据库日志也不会记录这个错误。所以即使做一个干净的还原,CHECKDB也不能发现问题。在做全备或者差备并成 为历史存档备份前,在主库上执行DBCC CHECKDB是发现这种问题的唯一途径。

  • 像ECC SQL SERVER bugs一样,更多的XPROC和COM对象bugs导致了同样的错误。如果XPROC中的代码错误地更新了内存,将出现同样模式的错误。

  • 过去10年中我们在存储方面排名第一的问题是Stale Read(从硬件高速缓存中返回页的前一版本而不是最版本).因为这只是页的较旧版本,所以校验和测试通常不会失败。这样一个场景:我妻子存了$500到 时我们的活期账户,几分钟后我取出$500.硬件高速缓存加载我妻子存款之前的账户结余。我妻子的存款被提交并写入了磁盘,但是硬件高速缓存没有被更新。 当我取钱时更新未能找到这笔存款,便错误地使用初始的账户结余更新了我的账户。SQL SERVER 不会直接知道这些事情,所以这就变成了一个逻辑事务丢失。

        在这种情况下,即使执行DBCC也不能发现这个错误。除了从事务日志备份恢复此数据库,并找出哪个页被持有同样的LSN的事务更新了两次,但是这本身就是一个无效的条件。

        我从来不愿意说DBCC不需要了。您应该像还原备份一样,时不时的运行一下。

 

Joe.TJ翻译整理,仅用于传播资讯之目的。