SQL Server 数据库内部存储基础

SQL Server 数据库内部存储基础  

http://blog.163.com/shi_123@126/blog/static/169899162009338527558/

     本节包含了SQL Server 数据库系统目录及表的内部数据存储。虽然在不理解内部细节的情况下也可以对SQL Server 数据库进行修复,但存储数据的细节将有助于开发有效的数据库修复程序,大大提高恢复成功率。(如果不需要深入了解这些信息,也可以跳过这部分讨论,进入关于恢复部分。)
   SQL Server 数据库有着良好的数据备份和恢复机制,但仍然不能避免由于数据库损坏,造成数据丢失。造成SQL Server数据库损坏的重要原因有:
(1) 操作问题,包括冷启动系统、热插拔硬盘、删除一些数据库文件等;
(2) 硬件问题,包括磁盘控制器的问题等;
(3) 操作系统问题,包括与系统相关的一些致命错误等。
修复一个受损的SQL 数据库,可以利用 SQL Server 自身的修复机制。但当SQL数据库损坏严重时,就要想办法直接从 MDF 文件的表中恢复原始数据。因此我们必须对MDF 文件内部存储格式有着详细的了解。

 6.1.1  数据页
SQL Server的MDF文件是页式存储格式。文件被划分成若干数据页。数据页是包含所有非文本或图像的数据的结构。就像使用SQL Server中的其他类型的页面一样,数据页面具有8KB(或8192字节)的固定大小。它们由三个主要部分组成:页面标题、数据行和行偏移量数组,如图6-1所示。


 


页面标题


96字节


 
 


 


 


数据行


 
 


 




行偏移量数组


 


 


 


 


 


 


图6-1  数据页的结构


 


页面标题


正如在图6-1中看到的,在每个数据页中,页面标题占用了前96个字节(剩下的8096字节用于数据和行偏移量)。表6-1显示的是页面标题所包含的信息。


 


 


字段                   包含


pageID        该页面在数据库中的文件编号和页码


nextPage      如果该页面处于一个页面链中,那么该字段表示下一个页面的案件编号和页码


prevPage      如果该页面处于一个页面链中,那么该字段表示上一个页面的案件编号和页码


objID         该页面所属的对象的ID


lsn           用于更改和更新该页面的日志序列号(LSN)值


slotCnt       该页面中所用的总的槽(行)数


level         该页面在索引中的级别(对于叶页通常为0)


indexId       该页面的索引ID(对于数据页面通常为0)


freeData      该页面中的第一个自由空间的字节偏移量


pminlen       行的固定长度部分的字节数


freeCnt       页面中的自由字节数


reservedCnt   由所有事务预留的字节数


xactresenved  由最近启动的事务预留的字节数


tornBits      每个扇区1位,用于检测残缺页的写


flagBits      包含关于页面其他信息的2字节位图


              表6-1 页面标题所包含的信息


 


数据页的页号是从0开始的,图6-2中的右下方区域是一个.MDF文件的第0页的标题信息的十六进制数显示方式。右上方区域是第0页标题信息的结构化显示方式。左侧区域显示的是页号和在文件中的偏移。


                   


数据行


页面标题下面是存储表实际数据行和区域。一个数据行最大的大小是8060字节。一个数据行不能跨越多个页面(文本或图像列除外,它们可以被存储在它们自己独立的页面中)。给定页面中存储的行数是根据表的结构及所存储的数据变化的。全部是固定长度列的表通常对于每个页面将存储相同数目的行;可变长度行将根据所输入的数据的实际长度,来决定存储能够容纳的行数。保持较短的行长度将会在一个页面中包含更多的行,从而减少I/O并提高缓存命中率。


 数据恢复


行偏移量数组


行偏移量数组是一块2字节的条目,每个条目指出页面中相应数据行开始的偏移量。每一行在该数组中有一个2字节的条目(正如“字符数据类型”部分中所讨论的,每个行需要10个字节的开销)。虽然这些字节没有被存储在包含数据的行中,但它们确实影响了一个页面所能包含的行数。


行偏移量数组指出一个页面中的行的逻辑顺序。例如,如果一个表具有群集索引,那么SQL Sever将以群集索引键的顺序来存储这些行。这并不意味着这些行将以群索引键的顺序物理地存储在页面中。相反,偏移量数组中的0槽指的是顺序中的第一行,1槽指的是第二行,以此类推。正如我们稍后在介绍实际的页面时将要看到的,这些行的偏移量可以位于页面中的任何位置。


对于表中的每一行,没有任何内部的全局行编号。SQL Sever组合使用页面中的文件编号、页码和槽编号来唯一地标识表中的每一行。


 


6.1.2  数据页


    可以使用DBCC PAGE语句来查看数据页的内容,它允许查看数据库中任何指定页面的页面标题、数据行和行偏移量表。只有系统管理员才可以使用DBCC PAGE。但是,因为通常不需要查看数据页的内容,所以在SQL Server文档中找不到更多有关DBCC PAGE的内容。如果想使用它,其语法如下:


DBCC PAGE(| dbid | dbname | , filenum, pagenum[ , printopt ])


DBCC PAGE包括表6-2中所示的参数。图6-3显示的是DBCC PAGE的示例输出。需要注意的是,DBCC TRACEON(3604)将会指导SQL Server把结果返回给客户,而不是像很多处理内部问题的DBCC命令的默认情况那样将错误日志返回给客户。


 


参数             描述


dbid             包含页面的数据库的ID


dbname           包含页面的数据库的名称


filenum          包含页面的文件编号


fagenum          文件内的页数


printopt         可选的打印选项;选用其中一个值:


                 0:默认值,打印缓冲区的标题和页面标题


                 1:打印缓冲区的标题、页面标题(分别打印每一行),以及


行偏移量表


                 2:打印缓冲区的标题、页面标题(整体打印页面),以及行


偏移量表


                 3:打印缓冲区的标题、页面标题(分别打印每一行),以及行偏移量表;每一行后跟分别列出的它的列值


                 表6-2 DBCC PAGE 命令的参数


 


DBCC TRACEON(3604)


GO


DBCC PAGE(5, 1, 88, 1)


GO


 


PAGE: (1:88)


----------------


BUFFER:


----------


BUF@0×10EC4E80


---------------------


bpage=0×1B8A4000      bhash=0×00000000   bpageno = (1:88)


bdbid=5                breferences = 0       bstat = 0×9


bspin=0                bnext=0×00000000


PAGE HEADER:


----------------


Page @0×1B8A4000


--------------------


m_pageld= (1:88)        m_headerVersion=1  m_type=1


m_typeFlagBits=0×0     m_level=0          m_fiagBits=0×0


m_objid=1977058079      m_indexid=0        m_prevPage=(0:0)


m_nextPage=(0:0)        pminlen=24         m_slotCnt=23


m_freeCnt=6010          m_freeData=2136    m_reservedCnt=0


m_isn=(3:243:2)         m_xactReserved=0    m_xdesld=(0:0)


m_ghostRccCnt=0         m_tornBits= -2147483591


 


Allocation Status


---------------------


GAM(1:2)=ALLOCATED  SGAM(1:3)=NOT ALLOCATED


PFS(1:10=0×60 MIXED_EXT ALLOCATED 0_PCT_FULL  DIFF(1:6)=CHANGED


ML(1:7)=NOT MIN_LOGGED


 


DATA


------


Slot 0 , Offset 0×631


----------------------------


Record Type=PRIMARY_RECORD


Record   Attributes=    NULL_BITMAP  VARIABLE_COLUMNS


1b8a4631: 00180030  20383034  2d363934  33323237   0…408 496-7223


1b8a4641: 34394143  01353230  00000009  00330005   CA94025……….3


1b8a4651: 003f0038  0058004e  2d323731  312d3233   8.?.N.X.172-32-1


1b8a4661: 57363731  65746968  6e686f4a  316e6f73   176WhiteJohnson1


1b8a4671: 32333930  67694220  52206567  654d2e64   0932 Bigge Rd.Me


1b8a4681: 206f6c6e  6b726150                       nlo Park


Slot 1,  Offset  0×b8


--------------------------------


Record Type=PRIMARY_RECORD


Record Attributes=     NULL_BITMAP VARIABLE_COLUMNS


1b8a40b8:  00180030  20353134  2d363839  30323037  0…415 986-7020


1b8a40c8:  34394143  01383136  00000009  00330005  CA94618………3


1b8a40d8:  00400038  00580051  2d333132  382d3634  8.@.Q. ×.213-46-8


1b8a40e8:  47353139  6e656572  6a72614d  6569726f  915GreenMarjorie


1b8a40f8:  20393033  64723336  2e745320  31342320  309 63rd St. #41


1b8a4108:  6b614f31  646e616c                      1Oakland


 


Slot 2 , Offset  0×110


-----------------------------


Record Type=PRIMARY_RECORD


Rexord Attributes=     NULL_BITMAP VARIABLE_COLUMNS


1b8a4110:  00180030  20353134  2d383435  33323737  0…415 548-7723


1b8a4120:  34394143   01353037  00000009  00330005  CA94705………3


1b8a4130:  003f0039   0055004d  2d383332  372d3539  9.?M.U.238-95-7


1b8a4140:  43363637   6f737261  6568436e  356c7972  766CarsonCheryl5


1b8a4150:  44203938   69777261  6e4c206e  7265422e  89 Darwin Ln.Ber


1b8a4160:  656c656b         79                      keley


 


/*  Data for slots 3 through 20 not shown */


 


Slot 21, Offset 0×1c0


----------------------------


Record Type  = PRIMARY_RECORD


Record Attributes =      NULL_BITMAP VARIABLE_COLUMNS


1b8a41c0:00180030  20313038  2d363238  32353730  0…801 826-0752


1b8a41d0:34385455  01323531  00000009  00330005  UT84152………3


1b8a41e0: 003d0039  0059004b  2d393938  322d3634  9.=.K.Y.899-46-2


1b8a41f0: 52353330  65676e69  6e6e4172  20373665  035RingerAnne67


1b8a4200: 65766553  2068746e  532e7641  20746c61  Seventh Av.Salt


1b8a4210: 656b614c  74694320        79            Lake City


 


Slot 22 , Offset 0×165


-----------------------------


Record Type =PRIMARY_RECORD


Record Attributes =     NULL_BITMAP VARIABLE_COLUMNS


1b8a4165:  00180030  20313038  2d363238  32353730  0…801 826-0752


1b8a4175:  34385455  01323531  00000009  00330005  UT84152………3


1b8a4185:  003f0039  005b004d  2d383939  332d3237  9.?.M.[.998-72-3


1b8a4195:  53273635  65676e69  626c4172  36747265  567RingerAibert6


1b8a41a5:  65532037  746e6576  76412068  6c61532e  7 Seventh AV. Sal


1b8a41b5:  614c2074  4320656b  797469              t Lake City


 


OFFSET TABLE:


---------------------


Row _Offset


22(0×16) -357(0×165)


21(0×15) -448(0×1c0)


20(0×14) -711(0×2c7)


19(0×13) -1767(0×6e7)


18(0×12) -619(0×26b)


17(0×11) -970(0×3ca)


16(0×10) -1055(0×41f)


15(0×f) -796(0×31c)


14(0×e) -537(0×219)


13(0×d) -1673(0×689)


12(0×c) -1226(0×4ca)


11(0×b) -1949(0×79d)


10(0×a) -1488(0×5do)


9(0×9) -1854(0×73e)


8(0×8) -1407(0×57f)


7(0×7) -1144(0×478)


6(0×6) -96(0×60)


5(0×5) -2047(0×7ff)


4(0×4) -884(0×374)


3(0×3) –1314(0×522)


2(0×2) -272(0×110)


1(0×1) –184(0×b8)


0(0×) -1585(0×631)


 


图6-3 DBCC PAGE的示例输出


 


正如所看到的,DBCC PAGE的输出分为4个主要部分:BUFFER、PAGEHEADER、DATA,以及OFFSET TABLE(真正的行偏移量数组)。BUFFER部分显示的是关于给定页面的缓冲区的信息。(这里的“缓冲区”是管理页面的内存结构。)


图6-3中的PAGE HEADER部分显示的是页面中所有标题字段的数据。(表6-1显示的是大多数这些字段的意义。)DATA部分包含每一行的信息。对于每一行,DBCC PAGE指出行在槽中的位置,以及该行在页面中的偏移量。然后,页面数据被分成三部分。左列指出的是所显示的数据在行中的字节位置。接下来的4列包含页面中存储的实际数据,以十六进制的形式显示。右列包含数据的字符表示。在该列中,虽然可能会显示出一些其他数据,但只有字符数据是可读的。


OFFSET TABLE部分显示的是页面末尾的行偏移量数组的内容。在图6-3中可以看到,该页面包含23行,其中第一行(以槽0表示)是以偏移量1585(0×631)开始的。页面中物理存储的第1行实际上是第6行,在行偏移量数组中具有偏移量96。DBCC PAGE以槽的编号顺序来显示行,即使如此,正如通过每个槽偏移量所看到的,这并不是页面中行物理存在的顺序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值