SQL Server数据库存储结构之IAM与数据页

标签:
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.