笔记17 DBCC IND()非常详细解释加dbcc page([GPOSDB],1,119,3)非常详细解释 2013-1-20
笔记17 DBCC IND()非常详细解释加dbcc page([GPOSDB],1,119,3)非常详细解释 2013-1-20
1 --DBCC IND()非常详细解释加dbcc page([GPOSDB],1,119,3)非常详细解释 2013-1-20 2 3 --在构建例子之前我们首先需要创建一个把地址转换为具体页码的函数。 4 USE [pratice] 5 GO 6 CREATE FUNCTION [dbo].f_get_page(@page_num BINARY(6)) 7 RETURNS VARCHAR(11) 8 AS 9 BEGIN 10 RETURN(CONVERT(VARCHAR(2),(CONVERT(INT,SUBSTRING(@page_num,6,1))*POWER(2,8))+ 11 (CONVERT(INT,SUBSTRING(@page_num,5,1))))+':'+ 12 CONVERT(VARCHAR(11), 13 (CONVERT(INT,SUBSTRING(@page_num,4,1))*POWER(2,24))+ 14 (CONVERT(INT,SUBSTRING(@page_num,3,1))*POWER(2,16))+ 15 (CONVERT(INT,SUBSTRING(@page_num,2,1))*POWER(2,8))+ 16 (CONVERT(INT,SUBSTRING(@page_num,1,1))))) 17 END 18 --根据master.sys.objects构建一张叫testIAM的数据表 19 SELECT * INTO testIAM FROM master.sys.objects 20 --然后我们根据之前所知晓的信息,获取testIAM对象的IAM地址,并根据f_get_page函数将地址转换为相应的页面 21 USE [pratice] 22 GO 23 SELECT total_pages,used_pages,data_pages, 24 first_page,root_page,first_iam_page, 25 dbo.f_get_page(first_page) first_page_address, 26 dbo.f_get_page(root_page) root_address, 27 dbo.f_get_page(first_iam_page) IAM_address 28 FROM sys.system_internals_allocation_units 29 WHERE container_id IN (SELECT partition_id FROM sys.partitions 30 WHERE object_id in (SELECT object_id FROM sys.objects 31 WHERE name IN ('test23'))) 32 33 34 --首先通过dbcc page(testdb,1,119,3)可以粗略看到页面分配情况 35 36 dbcc page([GPOSDB],1,119,3) 37 38 DBCC IND([GPOSDB],systempara,1) 39 40 --其次SQL Server还提供了一个更为友好的命令以找到各个类型的页面分布和它们的所在的文件号和页号。 41 42 --DBCC IND({'dbname'|dbid},{'objectname'|objectID}, 43 -- 44 --{nonclustered indid|1|0|-1|-2}[,partition_number]) 45 -- 46 --{'dbname'|dbid}表示数据库名或者数据库ID 47 -- 48 --{'objectname'|objectID}表示对象名或者对象ID 49 -- 50 --{nonclustered indid|1|0|-1|-2}表示显示行内数据分页及指定对象的行内IAM分页信息 51 -- 52 --1 :显示所有分页的信息,包括IAM分页,数据分页,所有存在的LOB分页和行溢出页,索引分页 53 -- 54 ---1: 显示所有IAM、数据分页、及指定对象上全部索引的索引分页. 55 -- 56 ---2: 显示指定对象的所有IAM分页 57 -- 58 --nonclustered indid:显示所有的IAM、数据分页以及一个索引的索引分页信息。 59 -- 60 --{partition_number}->可选,为了与中的DBCC IND命令向前兼容.它指定了一个特定分区号,如果不指定,显示所有分区的信息。 61 62 63 --以下是DBCC IND命令输出结果的字段描述: 64 65 字段名称 字段描述 66 67 PageFID 页面文件的ID 68 69 PagePID 页面编号 70 71 IAMFID 管理该页面的IAM页面所在的文件ID 72 73 IAMPID 管理该页面的IAM页面编号 74 75 ObjectID 表对象ID 76 77 78 79 IndexID 索引ID,0 代表堆, 1 代表聚集索引, 2-250 代表非聚集索引 大于250就是text或image字段 书本P18 80 81 82 83 PartitionNumber 表或索引所在的分区号码 84 85 86 87 PartitionID 包含该分页的分区ID 88 89 90 91 iam_chain_type 该页所属分配单元类型;行内数据、行溢出数据或Lob数据 92 93 94 95 PageType 分页类型:1:数据页面;2:索引页面;3:Lob_mixed_page;4:Lob_tree_page;10:IAM页面 96 97 98 IndexLevel 索引层级,0 代表叶级别分页 ;>0 代表非叶级别层次; NULL 代表IAM分页 99 100 101 102 NextPageFID 本层下一个分页所在的文件ID 103 104 105 106 NextPageFID 本层下一个分页ID 107 108 109 110 PrevPageFID 本层上一个分页所在的文件ID 111 112 113 114 PrevPageFID 本层上一个分页ID 115 116 117 ---------------------------------------------------------------------------------- 118 DBCC TRACEON(3604,-1) 119 120 DBCC PAGE([GPOSDB],1,106,3) 121 122 --PAGE HEADER: 123 -- 124 -- 125 --Page @0x0B908000 126 -- 127 --m_pageId = (1:106) m_headerVersion = 1 m_type = 10 128 --m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x0 129 --m_objId (AllocUnitId.idObj) = 277576027 m_indexId (AllocUnitId.idInd) = 1 130 --Metadata: AllocUnitId = 299666199216128 Metadata: PartitionId = 299666199216128 131 --Metadata: IndexId = 1 Metadata: ObjectId = 277576027 m_prevPage = (0:0) 132 --m_nextPage = (0:0) pminlen = 90 m_slotCnt = 2 133 --m_freeCnt = 6 m_freeData = 8182 m_reservedCnt = 0 134 --m_lsn = (6:524:11) m_xactReserved = 0 m_xdesId = (0:0) 135 --m_ghostRecCnt = 0 m_tornBits = 1 136 137 138 Dbcc page(testdb,1,224,2) 139 140 PAGE HEADER部分,即该页面的前96个字节。 141 142 m_pageId = (1:106) 当前页面号码 143 144 m_headerVersion = 1 版本号,始终为1 145 146 m_type = 10 当前页面类型,m_type=1表示数据页面 10:IAM页 147 148 m_typeFlagBits = 0x0 数据页和索引页为4,其他页为0 149 150 m_level = 0 该页在索引页(B树)中的级数,0表示为叶子节点 151 152 m_flagBits = 0x0 页面标志 153 154 m_objId (AllocUnitId.idObj) = 277576027 对象id 表id 155 156 m_indexId (AllocUnitId.idInd) = 1 索引ID,0 代表堆, 1 代表聚集索引, 2-250 代表非聚集索引 大于250就是text或image字段 书本P18 157 158 Metadata: AllocUnitId = 299666199216128 储单元的ID,sys.allocation_units.allocation_unit_id 159 160 Metadata: PartitionId = 299666199216128 数据页所在的分区号,sys.partitions.partition_id 161 162 Metadata: IndexId = 1 跟m_indexId一样 对象的索引号,sys.objects.object_id&sys.indexes.index_id 163 164 Metadata: ObjectId = 277576027 跟m_objId 一样 该页面所属的对象的id,sys.objects.object_id 165 166 m_prevPage = (0:0) 该数据页的前一页面 167 168 m_nextPage = (0:0) 该数据页的后一页面 169 170 pminlen = 90 定长数据所占的字节数为90个字节 171 172 m_slotCnt = 2 页面中的数据的行数,每页2条记录 173 174 m_freeCnt = 6 页面中剩余的空间,还剩6字节的空间 175 176 m_freeData = 8182 页面空闲空间的位置在8182这个位置 一个页面8KB约等于8192字节 页面空闲空间的位置在8182 177 说明这个页面已经放不下数据了 178 179 m_reservedCnt = 0 活动事务释放的字节数 180 181 m_lsn = (6:524:11) 日志记录号 182 183 184 m_xactReserved = 0 最新加入到m_reservedCnt领域的字节数 185 186 187 m_xdesId = (0:0) 添加到m_reservedCnt的最近的事务id 188 189 190 m_ghostRecCnt = 0 幻影数据的行数 191 192 193 m_tornBits = 1 页的校验位或者被由数据库页面保护形式决定页面保护位取代 194 195 196 197 198 199 --数据页面的LSN 其实跟事务日志的LSN是差不多的 200 --一些硬件系统经常发生漏写的现象(SQL Server要求将某个页面写入硬盘文件,I/O子系统报告写入已经完成, 201 --可是SQLServer下次读取的时候,读到的还是写入前的内容)。由于读到的老版本页面本身没有什么问题, 202 --Checksum和Tong Page算法都不能检查到错误。对这一类问题,SQLServer也有对策。在打开SQL Server启动参数开关-T818以后, 203 --SQL Server会在内存里维护一个哈希表,记录下自己所有做过写入动作的页面最新的LSN(Log Sequence Number)值。 204 --在下次读出页面的时候,会去比较这两个值是否相等。由于LSN是个自动增长的唯一值,每个发生新修改的页面, 205 --LSN的值会比原来的要大。所以如果读到的LSN与内存中存放的不一致,就说明上次的写入请求没有真正完成。 206 --这时824错误也会被触发。 207 208 209 210 211 212 --事务日志的LSN 213 --MSDN 解释 LSN 214 --SQL Server事务日志中的每个记录都由一个日志序列号 (LSN) 唯一标识。LSN 是这样排序的:如果 LSN2 大于 LSN1,则 LSN2 所标识的日志记录描述的更改发生在日志记录 LSN1 描述的更改之后。 215 -- 216 --发生重大事件的日志记录的 LSN 对于构造正确的还原顺序可能很有用。因为 LSN 是有顺序的,所以可以比较它们是否相等(即 <、>、=、<=、>=)。构造还原顺序时,这种比较很有用。 217 -- 218 -- 219 -- 220 -- 221 --注意 222 -- 223 -- 224 -- 225 -- 226 --LSN 是数据类型为 numeric 的值 (25,0)。算术运算(例如加法或减法)对 LSN 没有任何意义,请不要与 LSN 一起使用。 227 -- 228 -- 229 --RESTORE 顺序期间,在内部使用 LSN 跟踪数据还原到的时间点。还原备份后,数据被还原到与进行备份的时间点相对应的 LSN。差异和日志备份将还原的数据库推到稍后的时间,该时间与一个更高的 LSN 相对应。