SQL Server数据库存储结构之IAM与数据页
 (2011-08-25 16:53:56)
	
			
					(2011-08-25 16:53:56)		| 标签: it | 分类: 技术 | 
下面我们向空表中插入数据:
insert into TestTable values('testInRow', 'InRow', 'InRowData', 1, null)
再次查询allocation:
SELECT 
* 
得到如下结果:
http://s1/middle/882fba2bgab509ccb7720&690Server数据库存储结构之IAM与数据页"  TITLE="SQL 
Total_pages,used_pages,data_pages的值发生改变。
为什么插入了一行数据,会增加两页呢?其中一页是数据页,用来存放用户的数据,另外一页叫做IAM(索引分配映射)页,用来将数据页链接起来。连接方式如下图:
 
 
Sytem_internals_allocation_units表存放第一个数据页和第一个IAM页的指针。IAM按照数据页的顺序存放数据页的指针。数据页之间并无直接链接。
为更进一步说明这种存储结构,我们首先从查询Sytem_internals_allocation_units表:
SELECT total_pages,used_pages,data_pages,
 
 
WHERE container_id ='72057594038779904'
结果如下:
http://s14/middle/882fba2bgab509ebdebad&690Server数据库存储结构之IAM与数据页"  TITLE="SQL 
 
根据页面大小的规则,定义如下函数来计算页面数:
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))+
 
 
 
 
 
 
END
使用上述函数计算出数据页是79页,IAM页是80页。
接下来使用DBCC PAGE查询IAM页内容:
Metadata:
PartitionId = 72057594038779904 
Metadata:
ObjectId = 2105058535 
pminlen
= 90 
m_freeData
= 8182 
m_xactReserved
= 0 
m_tornBits
= 0 
 
Allocation Status
 
GAM
(1:2) = ALLOCATED 
PFS
(1:1) = 0x70 IAM_PG MIXED_EXT ALLOCATED 
ML
(1:7) = NOT MIN_LOGGED 
 
IAM: Header @0x5950C064 Slot 0, Offset 96
 
sequenceNumber
= 0 
indexId
= 0 
 
 
IAM: Single Page Allocations @0x5950C08E
 
Slot
0 = (1:79) 
Slot
3 = (0:0) 
Slot
6 = (0:0) 
 
 
IAM: Extent Alloc Status Slot 1 @0x5950C0C2
 
(1:0) 
加亮部分表明了IAM对应的分区信息,以及第一个数据页面指针指向79页。这与我们查询出的first_page值是一致的。一个IAM页面对应8个数据页,当超过8个数据页时,系统会从其对应的4GB空间(约512000个页面)中分配统一区的页面。当数据页超过可分配的页面数时,建立新的IAM页。
接下来查询数据页内容(部分省略):
Slot 0 Offset 0x60 Length 139
 
Record
Type = PRIMARY_RECORD 
Record
Size = 139 
Memory Dump @0x59ECC060
 
00000000: 
00000010: 
00000020: 
00000030: 
00000040: 
00000050: 
00000060: 
00000070: 
00000080: 
Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
 
ID
= 1 
 
Slot 0 Column 2 Offset 0x79 Length 9 Length (physical) 9
 
name
= testInRow 
 
Slot 0 Column 3 Offset 0x8 Length 100 Length (physical) 100
 
type
= InRow 
 
Slot 0 Column 4 Offset 0x82 Length 9 Length (physical) 9
 
summary
= InRowData 
 
Slot 0 Column 5 Offset 0x6c Length 4 Length (physical) 4
 
price
= 1 
 
Slot 0 Column 6 Offset 0x0 Length 0 Length (physical) 0
 
description = [NULL] 
这个页面里面的数据正是我们刚才插入的数据。
下面我们再插入一行数据:
insert into TestTable values('testInRow1', 'InRow1', 'InRowData1', 1, null)
现在查询Sytem_internals_allocation_units表中页面的分配,页面没有增加。因为没有产生新的数据页。
接下来我们循环插入1000条数据:
declare @i int
set @i=2
while @i<=1000
begin
 
 
end
再次查询页面分配,结果如下:
http://s3/middle/882fba2bgab50a535c762&690Server数据库存储结构之IAM与数据页"  TITLE="SQL 
First_page和first_iam_page没有变化,但是数据页数据增加了。
使用DBCC来查看数据页的信息,可以看到该页每一行的数据。
接下来查看IAM的信息,如下:
Slot
0 = (1:79) 
Slot
3 = (1:93) 
Slot 6 = (1:110) 
IAM: Extent Alloc Status Slot 1 @0x592EC0C2
 
(1:0) 
(1:184) 
(1:200) 
每一个指针都指向一个数据页。当分配数据页超过8个混合分区后,系统会为数据表分配统一分区。这里,系统为数据表分配184~191, 192~199两个统一分区。每个分区包含8页,加上8个混合分区的页面,一共是25个页面。这25个页面中,使用了19个数据页,加上1个IAM页共使用了20个页面。因为统一分区是顺序分配的, 所以可以计算出从195~199的页面没有被使用。用DBCC可以验证这个推算。
下面我们把插入的数据删除,然后再查看IAM的页面分配情况,发现页面分配不会因为数据删除而改变,数据页内仅仅是将数据清空而已。
 
PAGE: (1:89)
 
 
BUFFER:
 
 
BUF @0x0438E120
 
bpage
= 0x06036000 
bdbid
= 7 
bsampleCount
= 0 
blog
= 0x21bb7979 
 
PAGE HEADER:
 
 
Page @0x06036000
 
m_pageId
= (1:89) 
m_typeFlagBits
= 0x4 
m_objId
(AllocUnitId.idObj) = 29 
Metadata:
AllocUnitId = 72057594039828480 
Metadata:
PartitionId = 72057594038779904 
Metadata:
ObjectId = 2105058535 
pminlen
= 112 
m_freeData
= 7689 
m_xactReserved
= 7593 
m_tornBits
= -1698770727 
 
Allocation Status
 
GAM
(1:2) = ALLOCATED 
PFS
(1:1) = 0x60 MIXED_EXT ALLOCATED 
ML
(1:7) = NOT MIN_LOGGED 
 
 
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
 

 加载中…
加载中…