sql checksum

CHECKSUM is an option for page verification that is available at the database instance level and we can see what level of verification each of our databases are currently using by the following query:

CHECKSUM是用于页面验证的选项,可在数据库实例级别使用,我们可以通过以下查询查看每个数据库当前正在使用的验证级别:


SELECT name, page_verify_option_desc FROM sys.databases

We can also view the database options under its properties to see what option is enabled:

我们还可以在其属性下查看数据库选项,以查看启用了哪些选项:

In most cases we’ll notice that the Page Verify option is set to CHECKSUM and that’s because nowadays this is the default option for all databases. For Pre-SQL 2005 versions this was not the case, so occasionally when looking into database instances that have been migrated from earlier versions we might see one of the other Page Verify options selected; they are TORN PAGE DETECTION or NONE.

在大多数情况下,我们会注意到“页面验证”选项设置为“ CHECKSUM”,这是因为当今这是所有数据库的默认选项。 对于SQL 2005之前的版本,情况并非如此,因此,偶尔查看从早期版本迁移过来的数据库实例时,我们可能会看到选择了另一个“页面验证”选项之一。 它们是“残缺页检测”或“无”。

Having no page verification is a risky idea; the whole purpose of the Page Verify option is to provide a crucial check between when a page is written to disk and when it is read again to ensure its consistency, this gives an indicator to possible corruption issues at the IO subsystem so it is clearly a vital option to check and be aware of.

没有页面验证是一个冒险的想法; “页面验证”选项的整个目的是在何时将页面写入磁盘与何时再次读取页面之间提供关键检查,以确保页面的一致性,这为IO子系统可能出现的损坏问题提供了指示,因此很明显检查和注意的重要选择。

The TORN PAGE DETECTION option operates in a similar way to CHECKSUM. When a page is written the first 2 bytes of each 512 byte sector is stored in the page header and when the page is read back again SQL Server makes a comparison between the stored information and the sector bytes to detect any discrepancy and return an error if the comparison fails. The CHECKSUM option however bases its verification on a value calculated by using the entire page making the comparison between operations a much more thorough and effective option for page verification. In fact Books Online makes its recommendation very clear:

“ TONR PAGE DETECTION”选项的操作与CHECKSUM相似。 写入页面时,每个512字节扇区的前2个字节存储在页面页眉中,并且当再次读回页面时,SQL Server在存储的信息和扇区字节之间进行比较,以检测是否存在差异并在出现错误时返回错误比较失败。 但是,CHECKSUM选项的验证基于通过使用整个页面计算得出的值,从而使操作之间的比较成为页面验证的更彻底和有效的选项。 实际上,联机丛书非常明确地提出了以下建议:

最佳做法建议 (Best Practices Recommendations)

Set the PAGE_VERIFY database option to CHECKSUM.

将PAGE_VERIFY数据库选项设置为CHECKSUM。

So using a test database let’s have a look at the CHECKSUM option in action. I have a very small table consisting of three rows and a clustered index on the ID field and a non-clustered index on the LastName field.

因此,使用测试数据库,让我们看看实际的CHECKSUM选项。 我有一个非常小的表,该表由三行和ID字段上的聚集索引以及LastName字段上的非聚集索引组成。

As I have already written the data to disk I am going to use the undocumented DBCC WRITEPAGE command to force an alteration to one of the pages making it “inconsistent” and hopefully picked up by our CHECKSUM operation.

因为我已经将数据写入磁盘,所以我将使用未记录的DBCC WRITEPAGE命令来强制更改其中一个页面,使其“不一致”,并希望由我们的CHECKSUM操作进行选择。

Before I can do that I need to use another undocumented command DBCC IND to return the relevant Page ID’s for my non-clustered index as I want to ensure I am forcing an edit on the correct type of object. I need the relevant index ID so I will use the following query to return the specific ID for my non-clustered index:

在执行此操作之前,我需要使用另一个未记录的命令DBCC IND来为我的非聚集索引返回相关的页面ID,因为我想确保自己强制对正确类型的对象进行编辑。 我需要相关的索引ID,因此我将使用以下查询返回非聚集索引的特定ID:


SELECT * FROM sys.indexes WHERE name like 'NonClus%'

Which returns:

哪个返回:

Now I can use this ID with the DBCC IND command to find it’s corresponding pages. In this instance I am looking for rows with a PageType of 2, this being an index page.

现在,我可以将此ID与DBCC IND命令一起使用,以查找其对应的页面。 在这种情况下,我正在寻找PageType为2的行,这是一个索引页。

On the bottom row I can see the PagePID value of 166 and I can now pass this into the DBCC WRITEPAGE command to force an alteration; it uses the following syntax:

在底行,我可以看到166的PagePID值,现在我可以将其传递到DBCC WRITEPAGE命令中以强制更改。 它使用以下语法:

DBCC WRITEPAGE ({dbname | dbid}, fileid, pageid, offset, length, data , directORbufferpool)

DBCC WRITEPAGE({dbname | dbid},fileid,pageid,偏移量,长度,数据,directORbufferpool)

The final option directORbufferpool will be set to 1, this tells SQL to not write the change to the buffer pool first but write straight to disk. For this test we need to do this because making the change to the buffer pool will also create a new checksum making the change perfectly valid, which we don’t want to do. By issuing the command when the database is in single user mode I can create the page inconsistency scenario that we’re looking to test:

最终选项directORbufferpool将设置为1,这告诉SQL不要先将更改写入缓冲池,而是直接写入磁盘。 对于此测试,我们需要执行此操作,因为对缓冲池进行更改还会创建一个新的校验和,从而使更改完全有效,而我们不想这样做。 通过在数据库处于单用户模式下时发出命令,我可以创建我们要测试的页面不一致情况:


ALTER DATABASE SomeTestDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATEDBCC WRITEPAGE('SomeTestDatabase', 1, 166, 60, 1, 0x00, 1)ALTER DATABASE SomeTestDatabase SET MULTI_USER

Bringing the database back into multi user mode doesn’t return any errors, this is expected as the checksum operation will only occur when the page is read so let’s try a simple SELECT statement:

使数据库返回多用户模式不会返回任何错误,这是预期的,因为校验和操作仅在读取页面时才会发生,因此让我们尝试一个简单的SELECT语句:


SELECT *FROM [SomeTestDatabase].[dbo].[tblTestingTable]

In this case the query has worked perfectly fine, the rows have been returned and the query results have been displayed.

在这种情况下,查询运行得很好,返回了行并显示了查询结果。

This is because we “corrupted” the non-clustered index and as the clustered index represents the data itself we are not actually using the non-clustered index for this particular query, we can view the execution plan to confirm this:

这是因为我们“破坏了”非聚集索引,并且由于聚集索引代表数据本身,因此我们实际上并未针对特定查询使用非聚集索引,因此我们可以查看执行计划以确认这一点:

In order to use the non-clustered index we will add a hint to our SELECT query to effectively force SQL Server to use the non-clustered index (Index ID = 2) that we have modified with the DBCC WRITEPAGE command.

为了使用非聚集索引,我们将向我们的SELECT查询添加一个提示,以有效地强制SQL Server使用通过DBCC WRITEPAGE命令修改的非聚集索引(索引ID = 2)。


SELECT *FROM [SomeTestDatabase].[dbo].[tblTestingTable]WITH (INDEX(2))

Msg 824, Level 24, State 2, Line 2
SQL Server detected a logical consistency-based I/O error: incorrect checksum (expected: 0x9d3ce900; actual: 0x9d3ce950). It occurred during a read of page (1:166) in database ID 6 at offset 0x0000000014c000 in file

消息824,第2级,第2行,第24级
SQL Server检测到基于逻辑一致性的I / O错误:错误的校验和(预期:0x9d3ce900;实际:0x9d3ce950)。 它是在读取数据库ID 6中的页面(1:166)时在文件中的偏移量0x0000000014c000期间发生的

Now SQL Server has notified us of an incorrect checksum in the read operation of page 1:166 and the generated error message actually shows us the checksum value that the SELECT expected and what was returned.

现在,SQL Server在页面1:166的读取操作中通知我们错误的校验和,并且生成的错误消息实际上向我们显示了SELECT期望的校验和值以及返回了什么。

We can also see at the very beginning of the message that the error number is 824. This error, along with 823 and 825 specifically highlight potential corruption issues and we can trap and perform a notification of these error types using native functionality supplied by SQL Server Agent alerts.

我们还可以在消息的开头看到错误号为824。此错误以及823和825特别突出了潜在的损坏问题,我们可以使用SQL Server提供的本机功能捕获并执行这些错误类型的通知座席警报。


EXEC msdb.dbo.sp_add_alert @name=N'Error 824 - Error on SQL Server Page Read',@message_id=824,@severity=0,@enabled=1,@delay_between_responses=0,@include_event_description_in=0,@category_name=N'[Uncategorized]',@job_id=N'00000000-0000-0000-0000-000000000000'
GO

Here’s an example of creating an alert to capture Error 824 and we can then add a response to the alert to send an email to a group address warning us of any potential errors. This is highly recommended as these particular errors could indicate potential errors in the IO subsystem that require urgent attention.

这是创建警报以捕获错误824的示例,然后我们可以向警报添加响应,以向组地址发送电子邮件,警告我们任何潜在的错误。 强烈建议这样做,因为这些特定错误可能表示IO子系统中潜在的错误,需要紧急注意。

In addition to the CHECKSUM error being reported from a query we can run a database level consistency check and see the error being returned as well:

除了从查询中报告CHECKSUM错误外,我们还可以运行数据库级别的一致性检查并查看返回的错误:

Msg 8939, Level 16, State 98, Line 1
Table error: Object ID 245575913, index ID 2, partition ID 72057594040877056, alloc unit ID 72057594046119936 (type In-row data), page (1:166). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 133129 and -4.
Msg 8928, Level 16, State 1, Line 1
Object ID 245575913, index ID 2, partition ID 72057594040877056, alloc unit ID 72057594046119936 (type In-row data): Page (1:166) could not be processed. See other errors for details.
Msg 8980, Level 16, State 1, Line 1
Table error: Object ID 245575913, index ID 2, partition ID 72057594040877056, alloc unit ID 72057594046119936 (type In-row data). Index node page (0:0), slot 0 refers to child page (1:166) and previous child (0:0), but they were not encountered.
CHECKDB found 0 allocation errors and 3 consistency errors in table ‘tblTestingTable’ (object ID 245575913).
CHECKDB found 0 allocation errors and 3 consistency errors in database ‘SomeTestDatabase’.
repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (SomeTestDatabase).

讯息8939,第16级,州立98,第1行
表格错误:对象ID 245575913,索引ID 2,分区ID 72057594040877056,分配单元ID 72057594046119936(行内数据类型),页(1:166)。 测试(IS_OFF(BUF_IOERR,pBUF-> bstat))失败。 值是133129和-4。
消息8928,第16级,状态1,第1行
无法处理对象ID 245575913,索引ID 2,分区ID 72057594040877056,分配单元ID 72057594046119936(行内数据类型):页面(1:166)。 有关详细信息,请参见其他错误。
Msg 8980,第16级,状态1,第1行
表格错误:对象ID 245575913,索引ID 2,分区ID 72057594040877056,分配单元ID 72057594046119936(类型为行内数据)。 索引节点页面(0:0)的插槽0引用了子页面(1:166)和上一个子页面(0:0),但未遇到它们。
CHECKDB在表'tblTestingTable'(对象ID 245575913)中发现0个分配错误和3个一致性错误。
CHECKDB在数据库“ SomeTestDatabase”中发现0个分配错误和3个一致性错误。
repair_allow_data_loss是DBCC CHECKDB(SomeTestDatabase)发现的错误的最低修复级别。

As we know the modification was made in the non-clustered index the resolution is fairly straightforward as we just need to drop and recreate the index.

我们知道修改是在非聚集索引中进行的,因此解析非常简单,因为我们只需要删除并重新创建索引即可。


DROP INDEX [NonClusteredIndex-20170313-175804] ON [dbo].[tblTestingTable]
GOCREATE NONCLUSTERED INDEX [NonClusteredIndex-20170313-175804] ON [dbo].[tblTestingTable]
([LastName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,
DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO

We can see how important it is to have the CHECKSUM option enabled for page verification, apart from a small amount of overhead there really is no downside to using it and even then the overhead is insignificant when compared to the type of errors it is checking for.

我们可以看到启用CHECKSUM选项进行页面验证是多么重要,除了少量的开销外,使用它确实没有任何弊端,即使与要检查的错误类型相比,开销也微不足道。

When changing a database to use CHECKSUM it is important to know that the option isn’t used for pages that have already been written to disk and as such it will only be applied to new pages are written or when existing pages are modified and re-written to the IO subsystem.

更改数据库以使用CHECKSUM时,重要的是要知道该选项不用于已经写入磁盘的页面,因此,该选项仅适用于已写入磁盘的新页面,或者当现有页面被修改并重新创建时。写入IO子系统。

A common misconception regarding the CHECKSUM option is that it replaces the need for consistency checking databases. This is a very incorrect assumption; as we’ve seen the CHECKSUM error is only reported on the read operation of an inconsistent page, if the page isn’t read the error isn’t reported. However the biggest reason is that the DBCC CHECKDB routine performs a lot more thorough checking at the database level and includes checks that a CHECKSUM simply doesn’t cover, therefore the best practice is to combine CHECKSUM page verification and regular consistency checks.

关于CHECKSUM选项的一个常见误解是它取代了对一致性检查数据库的需求。 这是一个非常错误的假设。 如我们所见,CHECKSUM错误仅在不一致页面的读取操作中报告,如果未读取页面,则不会报告该错误。 但是,最大的原因是DBCC CHECKDB例程在数据库级别执行了更彻底的检查,并包括了CHECKSUM根本无法覆盖的检查,因此,最佳实践是将CHECKSUM页面验证与常规一致性检查结合起来。

翻译自: https://www.sqlshack.com/checksum-page-verification-in-sql-server/

sql checksum

sql checksum_SQL Server中的CHECKSUM页面验证相关推荐

  1. sql oltp_SQL Server中的内存中OLTP的快速概述

    sql oltp This is in continuation of the previous articles How to monitor internal data structures of ...

  2. net 架构师-数据库-sql server-001-SQL Server中的对象

    1.1 数据库的构成 1.2 数据库对象概述 1.2.1 数据库对象 RDBMS 关系数据库管理系统 对象:数据库.索引.事务日志.CLR程序集.表 .报表.文件组.全文目录.图表.用户自定义数据类型 ...

  3. sql crud_SQL Server中的CRUD操作

    sql crud CRUD operations are foundation operations every database developer and administrator needs ...

  4. sql dbcc_SQL Server中的DBCC命令的概念和基础

    sql dbcc Many DBA's and database developers aren't very familiar with DBCC commands (aka Database Co ...

  5. 尝试在Community Server中添加一个页面

    打开VS2005 新建一个文件夹localphotos,在文件夹中新建一个defaults.aspx 添加一个label控件在上面,设置属性TEXT 为Hello CS!,直接编译运行,在地址栏里打入 ...

  6. SQL SERVER中带参数的返回

    作者:网际浪子专栏(曾用名littlehb)  http://blog.csdn.net/littlehb/ CREATE PROCEDURE LoginUser   @loginUN char(50 ...

  7. aws rds监控慢sql_AWS RDS SQL Server中的初始Windows身份验证配置

    aws rds监控慢sql In this article, we will be exploring the process of enabling Windows authentication i ...

  8. sql隐式连接和显示链接_SQL Server中的嵌套循环联接–批处理排序和隐式排序

    sql隐式连接和显示链接 In SQL Server, it`s not always required to fully understand the internal structure, esp ...

  9. kerberos验证_SQL Server中的服务主体名称和Kerberos身份验证概述

    kerberos验证 This article gives an overview of Service Principal Name (SPN) for using the Kerberos aut ...

最新文章

  1. 老大让我优化数据库,我上来就分库分表,他过来就是一jio。。。
  2. 关于遮罩层无效的记录
  3. 机器人动力学建模实例(二):三连杆机械臂
  4. java里 currenttime_java 获取当前时间LocalDateTime currentTimeMillis java.util.Date
  5. linux 串口编程_ARM-Linux开发与MCU开发有何不同?上篇
  6. postgresql 备份_等保涉及的PostgreSQL数据库
  7. SAP Spartacus 4.0 deprecation 之一 - i18next-xhr-backend
  8. [BZOJ3994][SDOI2015]约数个数和
  9. java生产者消费者代码_Java实现Kafka生产者消费者代码实例
  10. 简洁版即时聊天---I/O多路复用使用
  11. Docker(三) 使用容器数据卷实现数据持久化与容器数据共享
  12. android 更新适配器,android – 当适配器数据更改时更新列表视图
  13. 数据结构之简单排序算法
  14. tkinter 中给某个文本加上滚动条_python中wx模块的具体使用方法
  15. 云栖号在线课堂—云服务器数据库快速入门特辑
  16. 【自定义WPS插件xlam】
  17. php 正则车架号,js 正则校验车架号VIN
  18. 常见的电脑系统故障原因及解决办法
  19. Linux上启动mysql不成功
  20. android微信支付开发过程

热门文章

  1. newifimini出厂固件_新路由mini固件|newifi新路由mini OS固件V3.2.1.1100 抢先版 - 极光下载站...
  2. Java抽象类、接口和内部类
  3. ubuntu 14.04下练习lua
  4. spring-boot-starter-parent的主要作用
  5. 谭浩强C语言第四版第九章课后习题7--9题(建立,输出,删除,插入链表处理)...
  6. PhotoshopCS5中将单位修改成百分比
  7. 【洛谷 P1772】 [ZJOI2006]物流运输(Spfa,dp)
  8. Python自动化之高级语法单例模式
  9. JS备忘--子父页面获取元素属性、显示时间,iframe之间互相调用函数
  10. [C++]用VC++来设置获得注册表的键值(问题解决)