IAM页,IAM链表,分配单元

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: from :http://www.sqlskills.com/BLOGS/PAUL/post/Inside-the-Storage-Engine-IAM-pages-IAM-chains-and-allocation-units.aspx 目录 IAM页... 1 IAM链表... 3 分配单元... 4 包含列... 4 宽行(Large Rows)... 5 分区... 5   IAM页 一个IAM(index allocation map)页跟踪单个文件中近4GB空间,和4GB的空间对齐。

 

from :http://www.sqlskills.com/BLOGS/PAUL/post/Inside-the-Storage-Engine-IAM-pages-IAM-chains-and-allocation-units.aspx

目录

IAM... 1

IAM链表... 3

分配单元... 4

包含列... 4

宽行(Large Rows... 5

分区... 5

 

IAM

一个IAMindex allocation map)页跟踪单个文件中近4GB空间,和4GB的空间对齐。这些4GB的块被叫做’GAM intervals’。一个IAM页跟踪的空间属于一个对象。

 

一个IAM页只能跟踪一个文件中的一个GAM interval,因此如果数据库有多个文件,或者有些文件大于4gb,那么一个实例被分配到多个文件或者一个文件中有多个GAM intervals,之后你就会发现每个对象需要的IAM页数量,来跟踪使用的空间。如果对象请求多个IAM页跟踪所有的扩展,那么这些IAM页就会被串起来。这个就是IAM链表。

 

每个IAM页有2个记录,一个是IAM头,一个是IAM位图。让我们看看DBCC PAGE。我们使用页拆分来看。运行dbcc ind 返回以下结果:

pagetyep列,你会发现有一个IAM页,IAM页的PageType 10。你可以在 Anatomy of a page中看到 更多的pagetype 代表的意思。

DBCC TRACEON (3604);

GO

DBCC PAGE ('pagesplittest', 1, 152, 3);

GO

m_pageId = (1:152)                   m_headerVersion = 1                  m_type = 10
m_typeFlagBits = 0x0                 m_level = 0                          m_flagBits = 0x200
m_objId (AllocUnitId.idObj) = 68     m_indexId (AllocUnitId.idInd) = 256
Metadata: AllocUnitId = 72057594042384384
Metadata: PartitionId = 72057594038386688                                 Metadata: IndexId = 1
Metadata: ObjectId = 2073058421      m_prevPage = (0:0)                   m_nextPage = (0:0)
pminlen = 90                         m_slotCnt = 2                        m_freeCnt = 6
m_freeData = 8182                    m_reservedCnt = 0                    m_lsn = (18:116:13)
m_xactReserved = 0                   m_xdesId = (0:0)                     m_ghostRecCnt = 0
m_tornBits = -1947725876

Allocation Status

GAM (1:2) = ALLOCATED                SGAM (1:3) = ALLOCATED
PFS (1:1) = 0x70 IAM_PG MIXED_EXT ALLOCATED   0_PCT_FULL                  DIFF (1:6) = CHANGED
ML (1:7) = NOT MIN_LOGGED

IAM: Header @0x620CC064 Slot 0, Offset 96

sequenceNumber = 0                   status = 0x0                         objectId = 0
indexId = 0                          page_count = 0                       start_pg = (1:0)


IAM: Single Page Allocations @0x620CC08E

Slot 0 = (1:143)                     Slot 1 = (1:153)                     Slot 2 = (1:154)
Slot 3 = (0:0)                       Slot 4 = (0:0)                       Slot 5 = (0:0)
Slot 6 = (0:0)                       Slot 7 = (0:0)


IAM: Extent Alloc Status Slot 1 @0x620CC0C2

(1:0)        - (1:272)      = NOT ALLOCATED

在页头上有些东西我们需要注意:

l  页类型为10

l  前一页,后一页为null,因为这个iam链表中没有其他的iam

l  Slot的个数是2,一个是iam头记录,一个是bitmap记录

l  页几乎是空的

IAM页头有一下元素:

Sequencenumber

         IAM页在IAM链表中的位置。IAM链表增加IAM页的时候会递增。

Status

         已经不使用

Objected

Indexed

         SQL Server 2000或者以前,表示所属的所以。在SQL Server 2005之后就未使用。

Page_count

         未使用,以前被用来记录单页分配的页数。

Start_pg

         保存了GAM interval的第一个page id

Single Page Alloctions array

         这些页是从混合扩展中分配的,这个队列只用在队列中的第一个IAM

Bitmap中每个GAM Interval 中的扩展占一个bit。当扩展被分配的时候bit被设置,如果没有就会被清除。在一个GAM interval中有两个IAM页对应不同的对象,怎么这2个不能有相同的bit设置-可是使用 dbcc checkdb检查。Dbcc page 你会发现没有扩展分配。你会发现输出直到以272页开始的扩展-这个是因为数据文件只有这么大。插入更多的列,在做dbcc page。下面是输出:

IAM: Single Page Allocations @0x620CC08E

Slot 0 = (1:143)                     Slot 1 = (1:153)                     Slot 2 = (1:154)
Slot 3 = (1:155)                     Slot 4 = (1:156)                     Slot 5 = (1:157)
Slot 6 = (1:158)                     Slot 7 = (1:159)


IAM: Extent Alloc Status Slot 1 @0x620CC0C2

(1:0)        - (1:152)      = NOT ALLOCATED
(1:160)      - (1:296)      =     ALLOCATED
(1:304)      - (1:400)      = NOT ALLOCATED

你会看到单页分配队列满了,之后分配切换到专用扩展。第一个可用的扩展从160页开始并且所有的扩展到296开始的扩展结束是已经被分配的。注意文件肯定增长,因为输出中增长到了400页。

IAM需要注意的信息:

         自身的从混合扩展中分配的单页不会再任何地方跟踪。

         他们可以从其他文件上被分配来跟踪任何位置的扩展。

 

 

IAM链表

如果我们继续增长文件填充表,之后我们需要另外一个IAM页来映射另外一个GAM interval。就形成了一个IAM链表。这个列表的IAM页分配到一个对象。链表并没有排序-IAM页被加入只是因为空间的需要。IAM页被编号,当被添加到列表的时候编号顺序排序。

不同的对象是否使用同一个IAM链表?在sql server 2000 sql server 2005 中答案是不一样的。

sql server 2000 中,以下状况都会有一个IAM链表:

         堆或者聚集索引

                   一个表只能有一个堆或者聚集索引。Index id的编号是分别是 0 1

         非聚集索引

                   Index id 2250(也就是你只能有249个索引)

         表完整的LOB存储

                   对于LOB列。的索引为全文索引,indexid255

Sql server 2000 中每个对象有251iam链表。我通常会说在sql server 2000中一个索引只有一个IAM链表。

 

分配单元

sql server 2005 或者之后的版本,很多东西都被修改。IAM链表和IAM页几乎相同,但是2者是不同的。一个表可以有750000IAM链表一下是新的3个事情分配IAM链表:

1.    堆或者b树(b树是index存储的内部结构)

2.    LOB 数据

3.    行溢出数据

我们叫这些空间分配单元叫分配单元。3个分配单元内部的名字:

1.       hobt分配单元(堆或b树,简称hobbit)。

2.       LOB分配单元

3.       SLOB分配单元(小LOB或者断LOB

外部名称叫做:

1.       IN_ROW_DATA分配单元

2.       LOB_DATA 分配单元

3.       ROW_OVERFLOW_DATA 分配单元

他们不是真正的IAM链表,因为不在跟踪一个索引的空间分配,他们的IAM页链表还是叫做IAM链表,单元的跟踪现在被叫做分配单元。区分他们,其实没什么不同点。

 

让我们快速的浏览sql server 2005中这3个新的特性的必要性和如何提升一个表的IAM链表数量。

 

包含列

非聚集索引可以把非key列加入到索引的叶子节点中。这个很有用:

1.       允许非聚集索引真正的覆盖查询,当查询结果多余16个列的时候或者查询的结果大于900个字节的时候(记住非聚集索引的key列被限制为16个列,900个字节)。

2.       允许被包含的列不是索引键的一部分(如 varchar(max)或者XML)。

3.       允许非聚集索引覆盖不需要所有的列都在key中。因为key 会被包含在索引的各个非叶子节点上,这样做可以减少索引的大小

一个空间缩小的例子:想象一个1000万行的行索引,键的长度为900字节,但是只有前面2个整型的键值被真正的使用,其他4个固定长度的列可以被保存在包含列中。900个字节8行可以填满一个数据页。也就意味着需要12500000个叶子节点,1562500倒数第二层节点等待,一共需要12500000 + 1562500 + 195313 + 24415 + 3052 + 382 + 48 + 6 + 1 = 14285717个页(包含1785717来存储非叶子节点)。

 

如果我们使用包含列key大小被缩小为8个字节,加上行头非叶子节点的行大小下降到15个字节。注意行上面的扇出还是8,因为所有的include存储在叶子节点上。因此有12500000个叶子节点,23278个上级节点,一共有12500000 + 23278 + 44 + 1 = 12523323个页(有23323个非叶子节点)。比较900个字节的key,减小了12%或者13.6GB

 

真正增加这个特性的理由是索引覆盖,优化器知道一个覆盖索引可以从索引中获取所有的查询结果,因此查询可以不发生额外的io,提高性能。

非聚集索引可以包含LOB列(在2005 中只能包含varchar(max),nvarchar(max),varbinary(max),XML)。这就索引单个LOB分配单元不可能更多因为每个索引可以有自己的LOB

所以一个索引需要2个分配单元一个是行内数据一个是LOB数据。

 

宽行(Large Rows

对于表设计者来说行限制大小为8060个字节是个灾难在sql server 2005这个限制就被取消了。方法是使用可变化长度列(varcharsqlvariant)超过一行最大一页的限制。

 

但是实际上超出了吗?这些列是有效的小lob数据列。这些数据被24个字节(可能是36,48,或者72个字节替换)的指针指向超出的的数据,就像lob一样被存储在一个独立的分配单元中-行溢出(或者SLOB)分配单元。这些值和LOB值一样被存储在文本页上的原理是一样的,只是使用了独立的分配单元。当第一个列值溢出的时候SLOB分配单元才会被创建。

 

这个特性在非聚集索引中也适用,考虑如果你把包含列加入到索引中,可能超出了一个页。使用900字节的限制被替换为8060字节的限制,没有使用扩展行溢出属性会太过短浅。

 

现在使用新特性,每个索引可以有3个分配单元,hobtLOB,SLOB。如果单单只有这些那么一个表的扩展单元最多可以有750个(一个IAM链表为一个分配单元,映射一个存储分配因此250个索引*3分配单元= 750IAM链表)。这里只有750个链表那么其他的从哪里来呢?

 

分区

一个表可以有1000个分区。分区是sql server 2005的新特性允许表,索引线性的划分为几段,每段都是独立存储(和独立的文件组类似)。分区是是独立基础。

 

每个表的分区或者表的分区是独立存储的,每个都需要自己的hobt分配单元。当然,每个分区的LOB值也需要存储。行溢出特性也是每行的,所以每个分区的行会溢出到SLOB分配单元和未分区的表和索引一样。表和索引的每个分区可以有3个分配单元(也就是3IAM链表)。

 

这就是1000的来历,每个表或者索引可以有1000个分区。250个索引*1000分区*3个分配单元 = 750000IAM链表。当然这个事情是不会发生的,但是是有可能的。

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
7月前
关于为什么要在链表中用malloc来分配内存
关于为什么要在链表中用malloc来分配内存
《阿里云产品手册2022-2023 版》——应用身份服务 IDaaS
《阿里云产品手册2022-2023 版》——应用身份服务 IDaaS
171 0
|
云安全 运维 安全
阿里云应用身份服务 IDaaS 重磅升级,云原生、高安全、更经济,极致用户体验!
3月9日,阿里云宣布 IDaaS 重磅升级,本次升级,阿里云将经年累月的身份业务、安全经验,融汇成新一代云原生的、经济的、便捷的、标准的 IDaaS EIAM (Employee IAM)产品,定位于企业身份云基座,为安全的企业管理、高效的业态升级保驾护航。
815 0
阿里云应用身份服务 IDaaS 重磅升级,云原生、高安全、更经济,极致用户体验!
|
存储 消息中间件 Cloud Native
阿里云新品发布会周刊第134期 丨 应用身份服务IDaaS重磅升级
新产品、新版本、新技术、新功能、价格调整,评论在下方,下期更新!关注更多新品发布会!
619 0
阿里云新品发布会周刊第134期 丨 应用身份服务IDaaS重磅升级
阿里云新品全域运营4A辅助器
阿里云新品全域运营4A辅助器
337 0
|
小程序 安全 数据安全/隐私保护
阿里云CIAM完整落地某国际大型零售企业
以统一认证、统一登录管理为核心,助力一站式解决多平台顾客身份管理难题。
1402 0
阿里云CIAM完整落地某国际大型零售企业
|
新零售 存储 安全
阿里云上新了!详解国内首个云上IDaaS CIAM解决方案
阿里云最近推出的国内首个云上IDaaS CIAM 顾客身份权限管理方案,基于云的灵活与弹性优势,以及阿里云深厚的基础设施积累,帮助零售、金融、文旅、教育、医疗等面向大众的行业实现统一的顾客身份管理,让顾客体验到跨终端统一、无摩擦的注册、登录体验,为核心业务增长护航。
2474 0
阿里云上新了!详解国内首个云上IDaaS CIAM解决方案
|
存储 算法 调度
分页储存管理.分段储存管理.虚拟储存管理
分页储存管理和分段储存管理是操作系统中常用的两种内存管理方式。 1. 分页储存管理: - 基本原理:将物理内存和逻辑内存划分为固定大小的页面和页面框,使得逻辑地址空间和物理地址空间可以对应起来。进程的逻辑地址空间被划分为多个固定大小的页面,每个页面与一个物理内存页面框对应。通过页表将逻辑地址映射到物理地址,实现地址转换。 - 优点:简单、灵活,能够提供较大的逻辑地址空间,适用于多道程序设计和虚拟内存管理。 - 缺点:存在内部碎片,会造成一定的存储空间浪费。 2. 分段储存管理: - 基本原理:将进程的逻辑地址空间划分为若干个逻辑段,每个逻辑段代表一个逻辑单位,如代码
198 0
|
存储 关系型数据库 MySQL
空闲空间管理和文件系统结构的优化策略
对于有科班背景的读者,可以跳过本系列文章。这些文章的主要目的是通过简单易懂的汇总,帮助非科班出身的读者理解底层知识,进一步了解为什么在面试中会涉及这些底层问题。否则,某些概念将始终无法理解。这些计算机基础文章将为你打通知识的任督二脉,祝你在编程领域中取得成功!
空闲空间管理和文件系统结构的优化策略