SQLSERVER里面一些跟硬件相关的错误跟SQLSERVER的一些数据页面保护技术

SQLSERVER里面一些跟硬件相关的错误跟SQLSERVER的一些数据页面保护技术

Checksum
 
SQL Server可以在写入每个页面时,根据页面里的数据算出一个校验值,一同存储到页面里去。当下次读取页面的时候,再根据这次读到的页面数据,算出一个新的校验值。如果写入和读出的数据一模一样,那么两个校验值一定是相等的。而如果两个校验值不相等,意味着上次SQLServer写入的数据和这次读出来的内容一定不同,现在读出来的数据有问题。通过这种方法,SQL Server能够发现数据页面损坏。
 
TornPage
 
残缺页(Torn Page)保护其实是一种对电源故障导致的页损坏进行检测的方法。例如,意外电源故障可能导致一个页面只有一部分被写入了磁盘。使用残缺页保护时,页的每个512B扇区末尾会放置一个2位签名(在将原来的2位复制到页头之后)。每次进行写操作时,这个签名在二进制数01和10之间交替,这样始终可以确定是否只有部分扇区写到磁盘。如果稍后读取页时发现某个位的状态不正确,则说明该页没有被正确写入,因此检测到问题页面,称为残缺页。相对于Checksum,残缺页检测使用的资源最少,但是它的算法太简单,无法检测到磁盘硬件故障导致的所有错误。
 
ShortTransfer
 
读到的数据长度比预期的少。例如,一个读取要求预期可以读到8KB的数据,可是实际只返回了4 KB。这也意味着当前读到的页面有损坏。
 
Bad PageId
 
在读到页面后,SQL Server会比较页面开头存储的页面编号和自己请求的目标编号。如果发现自己想要读取的页面是第200页,而读到的内容里显示它是第100页,SQL Server就会触发824错误。这种错误经常是因为I/O子系统没有正确地处理SQL Server的请求,传给SQL Server一个错误的页面,甚至是一个空页面。
 
RestorePending
 
在SQL Server 的企业版里,用户可以要求在做还原的时候跳过一些有损坏的页面(continue after error)。这些跳过的页面就被标识成“Restore Pending”。如果有用户想去访问它,也会遇到824错误。
 
StaleRead
 
一些硬件系统经常发生漏写的现象(SQL Server要求将某个页面写入硬盘文件,I/O子系统报告写入已经完成,可是SQLServer下次读取的时候,读到的还是写入前的内容)。由于读到的老版本页面本身没有什么问题,Checksum和Tong Page算法都不能检查到错误。对这一类问题,SQLServer也有对策。在打开SQL Server启动参数开关-T818以后,SQL Server会在内存里维护一个哈希表,记录下自己所有做过写入动作的页面最新的LSN(Log Sequence Number)值。在下次读出页面的时候,会去比较这两个值是否相等。由于LSN是个自动增长的唯一值,每个发生新修改的页面,LSN的值会比原来的要大。所以如果读到的LSN与内存中存放的不一致,就说明上次的写入请求没有真正完成。这时824错误也会被触发。

 

 

事务日志的LSN
MSDN 解释 LSN
SQL Server事务日志中的每个记录都由一个日志序列号 (LSN) 唯一标识。LSN 是这样排序的:如果 LSN2 大于 LSN1,则 LSN2 所标识的日志记录描述的更改发生在日志记录 LSN1 描述的更改之后。

发生重大事件的日志记录的 LSN 对于构造正确的还原顺序可能很有用。因为 LSN 是有顺序的,所以可以比较它们是否相等(即 <、>、=、<=、>=)。构造还原顺序时,这种比较很有用。

注意:LSN 是数据类型为 numeric 的值 (25,0)。算术运算(例如加法或减法)对 LSN 没有任何意义,请不要与 LSN 一起使用。

RESTORE 顺序期间,在内部使用 LSN 跟踪数据还原到的时间点。还原备份后,数据被还原到与进行备份的时间点相对应的 LSN。差异和日志备份将还原的数据库推到稍后的时间,该时间与一个更高的 LSN 相对应。

 

 

关于LSN 在每个数据页面头部里都有一个LSN: m_lsn = (6:524:11)  

--PAGE HEADER:
--
--
--Page @0x0B908000
--
--m_pageId = (1:106)                   m_headerVersion = 1                  m_type = 10
--m_typeFlagBits = 0x0                 m_level = 0                          m_flagBits = 0x0
--m_objId (AllocUnitId.idObj) = 277576027                                   m_indexId (AllocUnitId.idInd) = 1
--Metadata: AllocUnitId = 299666199216128                                   Metadata: PartitionId = 299666199216128
--Metadata: IndexId = 1                Metadata: ObjectId = 277576027       m_prevPage = (0:0)
--m_nextPage = (0:0)                   pminlen = 90                         m_slotCnt = 2
--m_freeCnt = 6                        m_freeData = 8182                    m_reservedCnt = 0
--m_lsn = (6:524:11)                   m_xactReserved = 0                   m_xdesId = (0:0)
--m_ghostRecCnt = 0                    m_tornBits = 1   

m_lsn = (6:524:11) :日志记录号

 

这里的LSN号跟事务日志的LSN不一样(不是同一个LSN),但是作用是一样的都是为了保证数据的一致性

posted @ 2013-01-20 00:52  桦仔  阅读(365)  评论(0编辑  收藏  举报