SQLServer2012 表IAM存储结构探究
SQLServer2012 表IAM存储结构探究
Author:zfive5(zidong)
Email: zfive5@163.com
引子
国庆节期间,一直在翻阅《程序猿的自我修养—链接、装载与库》。这本给我的感觉是越看越乱,但总的来说还不错。一句话--优秀程序猿就应该知道每个字节的意义。
看此书前的两本《深入解析SQLServer2008》和《Microsoft SQL Server 2005技术内幕:存储引擎》对IAM解读都是点到为止,让我满脑袋是一堆问号,内心特别想通过IAM找到数据库里的数据。这样才干让我为性能优化打开思路。
尽管两本书有些内容重叠,但它们绝对值得收藏和慢慢研读。
正文
分析样例与数据
通过以下SQL语句建分析的样例库和数据
|
CREATE TABLE[dbo].[Table6]( [a] [b] [c] ) ON[PRIMARY] DECLARE 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]) 须要开启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存储结构探究的更多相关文章
- cache数据库之表的存储结构
1.我们已经建了一个person类,接下来就是表的存储结构 2.打开Inspector,先输入rowid名字为p_RowID,选class->Storage 3.新建一个Storage,选择Ca ...
- 【Java数据结构学习笔记之一】线性表的存储结构及其代码实现
应用程序后在那个的数据大致有四种基本的逻辑结构: 集合:数据元素之间只有"同属于一个集合"的关系 线性结构:数据元素之间存在一个对一个的关系 树形结构:数据元素之间存在一个对多个关 ...
- Clickhouse的MergeTree表引擎存储结构
MergeTree存储的文件结构 一张数据表被分成几个data part,每个data part对应文件系统中的一个目录.通过以下SQL可以查询data parts的信息. select table, ...
- SQL Server 表和索引存储结构
在上一篇文章中,我们介绍了SQL Server数据文件的页面类型,系统通过96个字节的头部信息和系统表从逻辑层面上将表的存储结构管理起来,具体到表的存储结构上,SQL Server引入对象.分区.堆或 ...
- Berkeley DB的数据存储结构——哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)
Berkeley DB的数据存储结构 BDB支持四种数据存储结构及相应算法,官方称为访问方法(Access Method),分别是哈希表(Hash Table).B树(BTree).队列(Queue) ...
- 图->存储结构->邻接多重表
文字描述 邻接多重表是无向图的另一种链式存储结构. 虽然邻接表是无向图的一种很有效的存储结构,在邻接表中容易求得顶点和边的各种信息. 但是,在邻接表中每一条边(vi,vj)有两个结点,分别在第i个和第 ...
- 图->存储结构->邻接表
文字描述 邻接表是图的一种链式存储结构.在邻接表中,对图中每个顶点建立一个单链表,第i个单链表的结点表示依附顶点vi的边(对有向图是指以顶点vi为尾的弧).单链表中的每个结点由3个域组成,其中邻接点域 ...
- Mysql-Innodb : 从一个字节到整个数据库表了解物理存储结构和逻辑存储结构
首先要从Innodb怎么看待磁盘物理空间说起 一块原生的(Raw)物理磁盘,可以把他看成一个字节一个字节单元组成的物理存储介质 如果要在这块原生物理空间中插入一条记录,不能单单只插入数据,还需 ...
- 线性表之顺序存储结构(C语言动态数组实现)
线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...
随机推荐
- vue 使用localStorage保存页面变量到浏览器变量中
const STORAGE_KEY = 'todos-vuejs'//定义常量保存键值 export default{ fetch(){ return JSON.parse(window.localS ...
- 上传预览图片的插件jquery-fileupload
上传预览图片的插件jquery-fileupload github地址:https://github.com/blueimp/jQuery-File-Upload 中文文档:http://www.jq ...
- (转)vuex2.0 基本使用(1) --- state
Vuex 的核心是 store, 它是一个通过 Vuex.Store 构造函数生成的对象.为什么它会是核心呢?因为我们调用这个构造函数创建store 对象的时候,给它传递参数中包装了state, mu ...
- 启动Mysql时,提示error 2002 的解决办法
故障描述 启动时提示ERROR 2002(HY000) 启动服务时,提示the server quit without updating PID file. 解决方法一: 1.由于mysql是卸载后重 ...
- OpenCV:OpenCV图像旋转的代码
OpenCV图像旋转的代码 cv::transpose( bfM, bfM ) 前提:使用两个矩阵Mat型进行下标操作是不行的,耗费的时间太长了.直接使用两个指针对拷贝才是王道.不知道和OpenCV比 ...
- 【sqli-labs】 less10 GET - Blind - Time based. - Double quotes (基于时间的双引号盲注)
这个和less9一样,单引号改完双引号就行了 http://localhost/sqli/Less-10/?id=1" and sleep(5)%23 5s后页面完成刷新 http://lo ...
- 怎么在阿里云搭建一个WordPress博客(超详细教程)
想以正确的方式启动一个 WordPress 博客吗?我知道,这可能是一个令人恐惧的想法 -- 其实你并不孤单.但是,在帮助很多用户创建博客之后,我决定编写一份详细的指南,让任何没有技术知识的人都能拥有 ...
- marquee标签弹幕效果
播放个视频的时候看到很有趣的弹幕,想着前端能不能做个弹幕效果.弹幕是滚动的,所以首先想到了<marquee>标签.但事实上,<marquee>标签不是w3c的标准,只是主流的浏 ...
- BZOJ 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle 线段树 + 贪心
escription 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1&l ...
- Jmeter的参数签名测试
简介 参数签名可以保证开发的者的信息被冒用后,信息不会被泄露和受损.原因在于接入者和提供者都会对每一次的接口访问进行签名和验证. 签名sign的方式是目前比较常用的方式. 第1步:接入者把需求访问的接 ...