SQLServer2012 表IAM存储结构探究

Author:zfive5(zidong)

Email: zfive5@163.com

引子

国庆节期间,一直在翻阅《程序猿的自我修养—链接、装载与库》。这本给我的感觉是越看越乱,但总的来说还不错。一句话--优秀程序猿就应该知道每个字节的意义。

看此书前的两本《深入解析SQLServer2008》和《Microsoft SQL Server 2005技术内幕:存储引擎》对IAM解读都是点到为止,让我满脑袋是一堆问号,内心特别想通过IAM找到数据库里的数据。这样才干让我为性能优化打开思路。

尽管两本书有些内容重叠,但它们绝对值得收藏和慢慢研读。

     

正文

分析样例与数据

通过以下SQL语句建分析的样例库和数据

CREATE TABLE[dbo].[Table6](

[a]
[int] IDENTITY(1,1)NOTNULL,

[b]
[char](8000)NULL,

[c]
[int] NULL

) ON[PRIMARY]

DECLARE
@V1 INT

SET @V1=1

WHILE @V1<1000000

BEGIN

insert intoTable6(B,C)values(REPLICATE('c',8000),1)

SET @V1=@V1+1

END

SQL查询后数据例如以下图:

两个命令

两个命令各自是DBCC IND和 DBCC PAGE

DBCC IND 命令用于查询一个存储对象的内部存储结构信息,该命令有4个參数, 前3个參数必须指定。语法例如以下:

DBCC IND ( { 'dbname' | dbid }, { 'objname' | objid },{ nonclustered indid | 1 | 0 | -1 | -2 } [, partition_number] )

第一个參数是数据库名或数据库ID。

第二个參数是数据库中的对象名或对象ID,对象能够是表或者索引视图。

第三个參数是一个非聚集索引ID或者 1, 0, 1, or 2. 值的含义:

0: 仅仅显示对象的in-row data页和 in-row IAM 页。

1: 显示对象的所有页, 包括IAM 页, in-row数据页, LOB 数据页row-overflow 数据页 . 假设请求的对象含有聚集所以则索引页也包括。

-1: 显示所有IAM页,数据页, 索引页 也包含 LOB 和row-overflow 数据页。

-2: 显示所有IAM页。

Nonclustered index ID:显示索引的所有 IAM页, data页和索引页。包括LOB和 row-overflow数据页。

为了兼容sql server 2000,第四个參数是可选的,该參数用于指定一个分区号.假设不给定值或者给定0, 则显示所有分区数据。.

DBCC Page ({dbid|dbname},filenum,pagenum[,printopt])

详细參数描写叙述例如以下:

dbid: 包括页面的数据库ID

dbname:包括页面的数据库的名称

filenum:包括页面的文件编号

pagenum:文件内的页面

printopt:可选的输出选项。选用当中一个值:

0:默认值,输出缓冲区的标题和页面标题

1:输出缓冲区的标题、页面标题(分别输出每一行),以及行偏移量表

2:输出缓冲区的标题、页面标题(总体输出页面),以及行偏移量表

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

须要开启3604跟踪标志.

接下来通过运行

dbcc ind('A','Table6',-1),

能够看到例如以下图数据:

1:35646   Table6第1个IAM page

通过运行:

dbcc traceon(3604)

dbcc page('A',1,35646,1)

能够得到全部的:

1:35646   Table6第1个IAM page

1:35662    Table6第2个IAM page

1:35663    Table6第3个IAM page

1:1533712  Table6第4个IAM page

每个IAM page 都能够通过

dbcc traceon(3604)

dbcc page('A',1,35646,1)

dbcc page('A',1,35662,1)

dbcc page('A',1,35663,1)

dbcc page('A',1,1533712,1)

看到内部的数据,当中1,35646 数据例如以下:

DBCC 运行完成。假设 DBCC 输出了错误信息,请与系统管理员联系。

PAGE: (1:35646)

BUFFER:

BUF @0x000000047240BF40

bpage = 0x0000000286FAE000          bhash = 0x0000000000000000          bpageno = (1:35646)

bdbid = 7                           breferences = 0                     bcputicks = 0

bsampleCount = 0                    bUse1 = 58643                       bstat = 0x9

blog = 0x5adb215a                   bnext = 0x0000000000000000

PAGE HEADER:

Page @0x0000000286FAE000

m_pageId = (1:35646)                m_headerVersion = 1                 m_type = 10

m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x200

m_objId (AllocUnitId.idObj) = 98    m_indexId (AllocUnitId.idInd) = 256

Metadata: AllocUnitId = 72057594044350464

Metadata: PartitionId = 72057594040025088                                Metadata: IndexId = 0

Metadata: ObjectId = 1541580530     m_prevPage = (0:0)                  m_nextPage = (1:35662)

pminlen = 90                        m_slotCnt = 2                       m_freeCnt = 6

m_freeData = 8182                   m_reservedCnt = 0                   m_lsn = (1236:22589:9)

m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0

m_tornBits = 2069893598             DB Frag ID = 1

Allocation Status

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

PFS (1:32352) = 0x70 IAM_PG MIXED_EXT ALLOCATED   0_PCT_FULL             DIFF (1:6) = CHANGED

ML (1:7) = NOT MIN_LOGGED

DATA:

Slot 0, Offset 0x60, Length 94, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =                 Record Size = 94

Memory Dump @0x00000000139FA060

0000000000000000:   00005e00 00000000 00000000 00000000 00000000  ..^.................

0000000000000014:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000028:   00000000 01003d8b 00000100 3f8b00000100488b  ......=.....?

.....H.

000000000000003C:   0100 498b000001004a8b 00000100 4b8b0000  ....I.....J.....K...

0000000000000050:   01004c8b 00000100 4d8b0000 0100               ..L.....M.....

Slot 1, Offset 0xbe, Length 7992, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =                 Record Size = 7992

Memory Dump @0x00000000139FA0BE

0000000000000000:   0000381f 00000000 00000000 00000000 00000000  ..8.................

0000000000000014:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000028:   00000000 00000000 00000000 00000000 00000000  ....................

000000000000003C:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000050:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000064:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000078:   00000000 00000000 00000000 00000000 00000000  ....................

000000000000008C:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000000A0:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000000B4:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000000C8:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000000DC:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000000F0:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000104:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000118:   00000000 00000000 00000000 00000000 00000000  ....................

000000000000012C:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000140:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000154:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000168:   00000000 00000000 00000000 00000000 00000000  ....................

000000000000017C:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000190:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000001A4:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000001B8:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000001CC:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000001E0:   00000000 00000000 00000000 00000000 00000000  ....................

00000000000001F4:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000208:   00000000 00000000 00000000 00000000 00000000  ....................

000000000000021C:   00000000 00000000 00000000 00000000 00000000  ....................

0000000000000230:   00fcffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000000244:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000000258:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

000000000000026C:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000000280:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000000294:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

00000000000002A8:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

00000000000002BC:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

00000000000002D0:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

00000000000002E4:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

00000000000002F8:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

000000000000030C:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000000320:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000000334:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000000348:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

……

0000000000001CE8:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001CFC:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001D10:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001D24:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001D38:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001D4C:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001D60:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001D74:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001D88:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001D9C:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001DB0:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001DC4:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001DD8:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001DEC:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001E00:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001E14:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001E28:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001E3C:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001E50:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001E64:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001E78:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001E8C:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001EA0:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001EB4:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001EC8:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001EDC:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001EF0:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001F04:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001F18:   ffffffff ffffffff ffffffff ffffffff ffffffff  ....................

0000000000001F2C:   ffffffff ffffffff ffffffff                    ............

DBCC 运行完成。

假设 DBCC 输出了错误信息,请与系统管理员联系。

样例分析

每个IAM有两个SLOT,第1个IAM中第1个SLOT 中有8个页指针例如以下表(其他IAM第1个SLOT对如今的我还是问号)

指针(二进制)

页指针(十进制)

01003d8b 0000

0100 3f8b0000

0100488b  0000

0100 498b0000

01004a8b 0000

0100 4b8b0000

01004c8b 0000

0100 4d8b0000

1   35645

1   35647

1   35656

1   35657

1   35658

1   35659

1   35660

1   35661

Table6的每个IAM Page第2个SLOT。去除前4个字节,接下来是每BIT都是一个代表1个Extend(8个连续的Page)是否被本数据对象使用:

1:被本对象占用,

0:没有被本对象占用

以下列出Table6 中的每个IAM 第2个SLOT 部分重要数据

第一个IAM

dbcc traceon(3604)

dbcc page('A',1,35646,1)

0000000000000000:  0000381f 00000000 0000000000000000 00000000

……

0000000000000230:  00fcffff ffffffff ffffffffffffffff ffffffff

……

0000000000001F2C:  ffffffff ffffffff ffffffff

FE: 1111 1100

 

((231H-4)*8-2)*8=35664 

如图蓝色框部分

第二个IAM

dbcc traceon(3604)

dbcc page('A',1,35662,1)

0000000000000000:  0000381f feffffff ffffffffffffffff ffffffff

……

0000000000001F2C:  ffffffff ffffffff ffffffff

FE: 1111 1110

((1F2CH+12-4)*8+1)*8=511240 

如图蓝色框部分

第三个IAM

dbcc traceon(3604)

dbcc page('A',1,35663,1)

0000000000000000:  0000381f feffffff ffffffffffffffff ffffffff

……

0000000000001F2C:  ffffffff ffffffff ffffffff

FE: 1111 1110

((1F2CH+12-4+1FC2H+12-4)*8+1)*8=1022472

如图蓝色框部分

第四个IAM

dbcc traceon(3604)

dbcc page('A',1,1533712,1)

0000000000000000:  0000381f faffffff ffffffffffffffff ffffffff

…….

00000000000005B4:  ffffffff ffffffff ffffffff ffffff0000000000

FE: 1111 1010

((1F2CH+12-4+1FC2H+12-4+1F2CH+12-4)*8+1)*8=1533704

如图第一个蓝色框部分。低位第2个"1" BIT。代表了第二个篮框

某条记

然后通过DBCCPAGE 能够得到了真正的数据记录,比如最后一条记录

dbcc traceon(3604)

dbcc page('A',1,1627839,1)

DBCC 运行完成。假设 DBCC 输出了错误信息,请与系统管理员联系。

PAGE: (1:1627839)

BUFFER:

BUF @0x000000046F48EC40

bpage = 0x000000045C6FC000          bhash = 0x0000000000000000          bpageno = (1:1627839)

bdbid = 7                           breferences = 0                     bcputicks = 70

bsampleCount = 1                    bUse1 = 32444                       bstat = 0x9

blog = 0x15ab215a                   bnext = 0x0000000000000000

PAGE HEADER:

Page @0x000000045C6FC000

m_pageId = (1:1627839)              m_headerVersion = 1                 m_type = 1

m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x8200

m_objId (AllocUnitId.idObj) = 98    m_indexId (AllocUnitId.idInd) = 256

Metadata: AllocUnitId = 72057594044350464

Metadata: PartitionId = 72057594040025088                                Metadata: IndexId = 0

Metadata: ObjectId = 1541580530     m_prevPage = (0:0)                  m_nextPage = (0:0)

pminlen = 8012                      m_slotCnt = 1                       m_freeCnt = 79

m_freeData = 8111                   m_reservedCnt = 0                   m_lsn = (2320:17330:8)

m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0

m_tornBits = 194973556              DB Frag ID = 1

Allocation Status

GAM (1:1533696) = ALLOCATED         SGAM (1:1533697) = NOT ALLOCATED

PFS (1:1625688) = 0x44 ALLOCATED 100_PCT_FULL                            DIFF (1:1533702) = CHANGED

ML (1:1533703) = NOT MIN_LOGGED

DATA:

Slot 0, Offset 0x60, Length 8015, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP    Record Size = 8015

Memory Dump @0x000000001214A060

0000000000000000:   10004c1f 944a1800 63636363 63636363 63636363  ..L..J..cccccccccccc

0000000000000014:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc

0000000000000028:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc

000000000000003C:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc

0000000000000050:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc

0000000000000064:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc

……

0000000000001F04:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc

0000000000001F18:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc

0000000000001F2C:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc

0000000000001F40:   63636363 63636363 01000000 030000             cccccccc.......

OFFSET TABLE:

Row - Offset

0 (0x0) - 96 (0x60)

DBCC 运行完成。

假设 DBCC 输出了错误信息,请与系统管理员联系。

结论

IAM的结构已经OK 90%,但那10%还是继续问号。期待不远的将来迎来解惑之篇

SQLServer2012 表IAM存储结构探究的更多相关文章

  1. cache数据库之表的存储结构

    1.我们已经建了一个person类,接下来就是表的存储结构 2.打开Inspector,先输入rowid名字为p_RowID,选class->Storage 3.新建一个Storage,选择Ca ...

  2. 【Java数据结构学习笔记之一】线性表的存储结构及其代码实现

    应用程序后在那个的数据大致有四种基本的逻辑结构: 集合:数据元素之间只有"同属于一个集合"的关系 线性结构:数据元素之间存在一个对一个的关系 树形结构:数据元素之间存在一个对多个关 ...

  3. Clickhouse的MergeTree表引擎存储结构

    MergeTree存储的文件结构 一张数据表被分成几个data part,每个data part对应文件系统中的一个目录.通过以下SQL可以查询data parts的信息. select table, ...

  4. SQL Server 表和索引存储结构

    在上一篇文章中,我们介绍了SQL Server数据文件的页面类型,系统通过96个字节的头部信息和系统表从逻辑层面上将表的存储结构管理起来,具体到表的存储结构上,SQL Server引入对象.分区.堆或 ...

  5. Berkeley DB的数据存储结构——哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)

    Berkeley DB的数据存储结构 BDB支持四种数据存储结构及相应算法,官方称为访问方法(Access Method),分别是哈希表(Hash Table).B树(BTree).队列(Queue) ...

  6. 图->存储结构->邻接多重表

    文字描述 邻接多重表是无向图的另一种链式存储结构. 虽然邻接表是无向图的一种很有效的存储结构,在邻接表中容易求得顶点和边的各种信息. 但是,在邻接表中每一条边(vi,vj)有两个结点,分别在第i个和第 ...

  7. 图->存储结构->邻接表

    文字描述 邻接表是图的一种链式存储结构.在邻接表中,对图中每个顶点建立一个单链表,第i个单链表的结点表示依附顶点vi的边(对有向图是指以顶点vi为尾的弧).单链表中的每个结点由3个域组成,其中邻接点域 ...

  8. Mysql-Innodb : 从一个字节到整个数据库表了解物理存储结构和逻辑存储结构

    首先要从Innodb怎么看待磁盘物理空间说起   一块原生的(Raw)物理磁盘,可以把他看成一个字节一个字节单元组成的物理存储介质   如果要在这块原生物理空间中插入一条记录,不能单单只插入数据,还需 ...

  9. 线性表之顺序存储结构(C语言动态数组实现)

    线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...

随机推荐

  1. php解析 html类库 simple_html_dom

    如果从字符串加载html文档,需要先从网络上下载.建议使用cURL来抓取html文档并加载DOM中. 查找html元素 可以使用find函数来查找html文档中的元素.返回的结果是一个包含了对象的数组 ...

  2. ABP的一些特性 (Attribute)

    大家应该很熟悉Attribute这个东西吧,ABP里面扩展了一些特性,做过滤权限,返回内容等进行控制,在这里小记下,方便后续查看. [DontWrapResult]  //ABP默认对返回结果做了封装 ...

  3. dotnet core 发布配置(测试数据库和正式数据库自动切换)

    一.起源 在进行项目开发时,常常要求开发环境,测试环境及正式环境的分离,并且不同环境运行的参数都是不一样的,比如监听地址,数据库连接信息等.当然我们把配置信息保存到一个文件中,每次发布的时候,可以先修 ...

  4. php数据库分页

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 经典实用SQL Server语句大全总结(一)

    简要介绍基础语句:1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创 ...

  6. jenkins如何实现重新发布历史构建记录里的版本

    Jenkins以前打包都会将打出的拷贝放到历史版本里放到Daily_Result里,昨天不只是误操作还是系统问题,误将一个历史版本的包删掉了,而且这个包是之前比较稳定的一个版本,需要重新给客户发,所以 ...

  7. Swiper 3D flow轮播使用方法

    swiper 的3d轮播效果,移动端适用 (1). 如需使用Swiper的3d切换首先加载3D flow插件(js和css). <head> <link rel="styl ...

  8. javaee字符缓冲输出流

    package Zjshuchu; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOExcepti ...

  9. JAVA中浅复制与深复制

    1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...

  10. Android 性能测试初探(五)

    书接上文 Android 性能测试初探之 GPU(四) 前文说了的一些性能测试项大家可能都听说,接下来我们聊聊大家不常关注的测试项- 功耗 . 功耗测试主要从以下几个方面入手进行测试 测试手机安装目标 ...