设为首页 收藏本站
查看: 699|回复: 0

[经验分享] SQL Server 2008存储结构之IAM结构

[复制链接]

尚未签到

发表于 2016-11-4 09:39:22 | 显示全部楼层 |阅读模式
  索引分配映射(Index Allocation Map,IAM)页面在4 GB的区间中跟踪被一个分配单元所使用的区。一个分配单元就是一组页面,这些页面属于一个数据表或索引的单个分区。它由下面三种类型页面中的一种组成:含有常规的行内数据的页面、含有大型对象(Large Object,LOB)数据的页面和含有行溢出数据的页面。 其实SQL Server的数据页面类型与Oracle的段的概念有些类似,一个对象包含若干段,而一个段只能属于一个对象。
  假如一张在四个分区上的含有所有三种类型的数据(行内数据、LOB数据和行溢出数据)的表将会有至少12个IAM页面。单张IAM页面也是仅仅覆盖单个文件的4GB区间,所以如果分区跨越多个文件,那么就会有多个IAM页面,同时如果文件大小超过4GB,并且分区使用了一个4 GB区间以外的数据页,那么也将会有额外的IAM数据页。
  一个IAM数据页包含一个页头(IAM页头),该页头包含有8个页面指针槽,还有一组比特位用来将一个范围内的区映射到一个文件,这个文件并不必一定就是IAM页面所在的那个文件。页头包含有在IAM映射范围内的第一个区的地址。8个页面指针槽可能包含指向某些属于相关对象页面的指针,这些对象被包含在混合类型的区中,对一个对象来说,只有第一个IAM页面含有这些指针的值。一旦一个对象占用的页面超过8个,它所有的区都会是统一类型的区——这意味着一个对象决不会需要超过8个指针来指向处于混合类型区中的页面。如果一张表中的数据行已被删除,该表实际上可以使用的指针数不到8个。比特位映射中的每一个比特位代表了该范围内的一个区,而不论该区是否被分配给了拥有该IAM的对象。如果一个比特位是打开的,那么在此范围内相关的区就是被分配给拥有 IAM的对象的;如果一个比特位是关闭的,那么此范围内相关的区没有被分配给拥有该IAM的对象。
  IAM页面在需要的时候被分配给每一个对象,并且位于数据库中的随机位置。每一个IAM页面覆盖的可能范围大约是512 000个页面。
  看概念总归是比较枯燥的,我们可以构建一个具体的例子。
  在构建例子之前我们首先需要创建一个把地址转换为具体页码的函数。
#div_code img { border: 0px none; }CREATE FUNCTION [dbo].f_get_page(@page_num BINARY(6))
RETURNS VARCHAR(
11)
AS
BEGIN
RETURN(CONVERT(VARCHAR(
2),(CONVERT(INT,SUBSTRING(@page_num,6,1))*POWER(2,8))+
(CONVERT(
INT,SUBSTRING(@page_num,5,1))))+':'+
CONVERT(VARCHAR(11),
(CONVERT(
INT,SUBSTRING(@page_num,4,1))*POWER(2,24))+
(CONVERT(
INT,SUBSTRING(@page_num,3,1))*POWER(2,16))+
(CONVERT(
INT,SUBSTRING(@page_num,2,1))*POWER(2,8))+
(CONVERT(
INT,SUBSTRING(@page_num,1,1)))))
END
--根据master.sys.objects构建一张叫testIAM的数据表
SELECT * INTO testIAM FROM master.sys.objects
--然后我们根据之前所知晓的信息,获取testIAM对象的IAM地址,并根据f_get_page函数将地址转换为相应的页面
SELECT total_pages,used_pages,data_pages,
first_page,root_page,first_iam_page,
testdb.dbo.f_get_page(first_page) first_page_address,
testdb.dbo.f_get_page(root_page) root_address,
testdb.dbo.f_get_page(first_iam_page) IAM_address
FROM sys.system_internals_allocation_units
WHERE container_id IN (
SELECT partition_id FROM sys.partitions
WHERE object_id in (
SELECT object_idFROM sys.objects
WHERE name IN (
'testIAM')))

dbcc page(testdb,
1,80,3)


DSC0000.jpg

  从dbcc page(testdb,1,80,3)可以得到以下信息
DSC0001.jpg

  因为master.sys.objects的对象只有49条数据,所以只分配了2个页面,根据前文所述,分配8个页面(包括8)以内的对象,SQL Server将以把该对象的数据分配到混合类型的分区上,如上SQL Server给予testIAM表只分配了第一个文件的第77和第89个页面,而并没有分配同一类型的分区的页面。  
  假如我们master.sys.objects的数据反复插入testIAM表,让我们观察一下相应的页面分配情况。
#div_code img { border: 0px none; }declare @maxtime int
set @maxtime=0
while @maxtime<20
begin
insert into testiam
select * from sys.objects
set @maxtime=@maxtime+1
end
select * from testiam
--我们首先还是运行以下system_internals_allcation_units系统表
SELECT total_pages,used_pages,data_pages,
first_page,root_page,first_iam_page,
testdb.dbo.f_get_page(first_page) first_page_address,
testdb.dbo.f_get_page(root_page) root_address,
testdb.dbo.f_get_page(first_iam_page) IAM_address
FROM sys.system_internals_allocation_units
WHERE container_id IN (
SELECT partition_id FROM sys.partitions
WHERE object_id in (
SELECT object_idFROM sys.objects
WHERE name IN (
'testIAM')))

--通过上面的结果,我们可以观察到这次SQL Server共分配了17个页面,其中使用了15个页面,而数据页面只有14个,这是为什么呢?
--接着我们再次运行dbcc page命令
dbcc page(testdb,
1,80,3)


DSC0002.jpg

  结果如下
DSC0003.jpg

  从上述我们可知,slot 0到slot 7一共分配了8个混合类型区的页面,由于已经超过8页,所以SQL Server再次分配空间时,就会把同一类型的区分配给该对象,一个区包括8个页面,所以SQL Server为testIAM表共分配了16个页面,数据页面14个,已使用的页面除了数据页面还包括该表的一个IAM管理页面。
  还是通过Internals Viewer插件让我们看一下IAM页的情况吧
DSC0004.jpg

  比较有意思的是SQL Server 2008为什么不从一开始就为每一个对象分配同一类型的页面,仅仅是为了节约空间?还是为了与之前版本的兼容性?就不得而知了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-295620-1-1.html 上篇帖子: 在 SQL Server 2005 中配置数据库邮件 下篇帖子: SQL Server 2005中处理表分区问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表