CHECKSUM 和 Tempdb

可能您有印象从 SQL Server2005 开始有一个选项开启在用户数据库上的 CHECKSUM 功能。更多细节参见 http://blogs.msdn.com/sqlserverstorageengine/archive/2006/06/29/Enabling-CHECKSUM-in-SQL2005.aspx .

事实上,在SQL Server2005中每个新建的数据库都是默认开启CHECKSUM功能,但从其他版本升级到SQL Server2005的数据库不会自动开启,需要开启时使用ALTER DATABASE命令。启用CHECKSUM是十分重要的,在查询的一部分需要读数据页或者运行DBCC CHECKDB命令式,它能使数据库检测到IO路径上的损坏状况(如磁盘故障)。美中不足的是,SQL Server不允许对tempdb启用CHECKSUM。即使我们在用户数据库上启用了CHECKSUM,由于磁盘问题导致的页损坏还是会通过tempdb的这个漏洞进入该用户数据库。以下描述了这样一个示例场景

  • 示例场景:

批量导入数据到一个临时表格然后再导入用户数据库。用户数据库启用了CHECKSUM,所以新页面写入磁盘的时候会计算CHECKSUM。但有没有不计算CHECKSUM的情况呢?如果因磁盘损坏而损坏的页面先进入tempdb再进入用户数据库时,SQL Server无法知道页面是否损坏,也不会检测这些进入用户数据库的页面。是的,当页面随后被读取时,SQL Server有可能检测出错误也有可能检测不出,取决于是如何损坏的。例如,如果一个整数值发生了位翻转时,它就会被发现。

 

在SQL Server2008中,temp数据库中允许开启 CHECKSUM则弥补了上述不足。你可以用这样的命令开启

ALTER DATASE tempdb set PAGE_VERIFY CHECKSUM

 

对于新安装的SQL Server2008,所有的tempdb都默认开启CHECNSUM功能,用户可以使用ALTER DATABASE功能关闭这一功能,但是我们不建议这样做。对于从其它版本升级到SQL Server2008中的数据库,用户可以明确开启在tempdb中的CHECKSUM功能,对性能的影响也非常小(对CPU使用率的影响小于2%),基本和在其他用户数据库中消耗一样。不同之处在于,因为CHECKSUM功能只在页写入磁盘的时候运行而tempdb没有checkpoint,所以tempdb只在内存压力大时写入磁盘。所以你可能不会看到tempdb中有很多次计算CHECKSUM。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
页面
  checksum   SQL2005 的新功能,提供了一种比残缺页检测强大的机制检测 IO 方面的损坏。以下是详细描述:

页面 CHECKSUM:

在数据库页面从被写入磁盘到被SQL Server读取的这段时间内,有可能由于外界原因发生损坏。比如I/O设备的损坏,驱动的损坏或者由于电源不稳没有写完整。Checksum机制使SQL Server可以检测到这些损坏。需要注意的是,Checksum机制只能使我们确定是不是I/O子系统引起页面损坏,但是不能自动修复它们。作为管理员,我们可以利用这些信息来辨识出并更换损坏的I/O设备,也可以利用重建索引或者修复损坏文件等方法修复已发生的页面损坏。

Checksum功能可以由Alter Database命令在数据库上逐个开启和关闭每一个数据库上的。当开启Checksum时,SQL Server会在页面被写入和被读取的时候计算页面的ChecksumSQL Server基于页面上的位模式计算Checksum,储存在页头部,然后发一个I/O来写页面。SQL Server在读取页面时用相同的方法再计算一次checksum,并与储存在页面头的checksum值进行比较。如果结果相同则说明在读写周期内页面没有损坏。计算checksum的算法是复杂的,因为会涉及到多个页面的读写,增加CPU的负荷,可能会影响系统的吞吐量。此外,checksum不是与页面位模式一一对应的,不同页面也有可能有相同的checksum值,所以有极小的可能性事页面损坏检查不出来。

我们对以下几种情况特别做一些说明:

l  数据库创建一段时间后才开启checksum

只有在开启checksum功能后每次写页面时才会计算checksum,读取页面时才会重新计算。如果数据库创建之初没有开启Checksum,会有一些页没有记录下checksum。当读取这些页面时SQL Server不会计算checksum,因为没有可以用来比较的checksum,计算就没有意义。目前没有命令或工具强制计算数据库所有页面的checksum。这样做并没有太大的好处。试想,当数据页面已经被破坏时,我们只能计算损坏的checksum,而不知道正常情况下的checksum,损坏也无从检测。当然,如果有这样的命令或工具存在,我们就能检测到由于位损坏(如一个有效的页在被写入到磁盘后发生损坏)引起的页面损坏,或者在数据库文件被转移或者复制到其他媒介的时检测到损坏了。

l  停止checksum功能

当不希望checksum消耗CPU资源或者确信I/O系统可靠的时候,您可以停止Checksum功能。停止后,不再计算和记录checksum值。这种情况下, SQL Server就可能受到外界造成的页面损坏,一个检测不到的损坏可能导致:

o      数据丢失,除非运行全备份恢复(前提是日志备份没有被破坏)

o      潜在的应用程序异常,特别是在损坏没有改变页面结构而只是改变了某些数据时。

o      降低数据库的可用性,因为必须要执行介质恢复来修正损坏。

l  如何验证数据库所有页的checksum

使用DBCC CHECKDB命令,最好加上PHYSICAL_ONLY参数以降低资源的消耗。

l  数据库开启残缺页(torn page)检测

数据库的Checksum检测和残缺页检测不能同时开启。因为checksum机制对于页面损坏的验证比残缺页更严格,而产生checksum匹配但是页面残缺的可能性极小,所以开启checksum相当于自动获取残缺页检测。如果您关闭了页面的checksum功能,那我们建议您开启残缺页检测,用较小的代价尽可能检测I/O子系统异常。

备份 checksum

备份checksum和页面checksum算法一样,每当页面做备份时计算checksum,只不过多个页面checksum的值将合并成一个备份checksum值。备份checksum储存在备份媒介,而不是页面中。备份期间您可以选择生成备份checksum用于恢复备份时检测备份时候损坏。另外,如果页面checksum可用,可以在备份和恢复过程中用于确认。

你可能感兴趣的:(数据库SQL,server)