SQL Server数据行的物理空间分配

SQL Server数据行的物理空间分配

104344808.png


一、页(page)

1、基本概念

  页是SQL Server存储数据的基本单位,每一页为8KB(8192字节)。页是SQL Server可以读写的最小I/O单位,即使只访问一行,SQL Server也要读取整个页。


093619821.png

  SQL Server有以下8种类型的页

(1)数据页:是保存除text/ntext/image类型外的数据行

(2)索引页:保存索引信息

(3)页面可用空间(PFS:Page Free Space)页:保存可用页空间信息,Page ID=1 。

(4)文本/图像页:保存text/ntext/image类型的数据

(5)全局分配映射(GAM)页:保存已经分配的盘区信息,Page ID=2 。SGAM,Page ID=3 。

(6)索引分配映射页(IAM):保存一个表或索引使用的盘区信息

(7)批量修改映射(BCM:Bulk Changed Map)页:保存在上次backup   log时执行批量操作所修改的盘区信息,Page ID=7 。

(8)差量修改映射(DCM:Differential Changed Map)页:保存上次backup database差异备份时所修改的盘区信息,Page ID=6 。


2、数据页

(1)标头(Header)

  每一个数据页都包含一个96字节的标头,SQL Server 2005使用了64字节,其它32字节作为保留。标头包含的信息如下(摘自《深入解析SQL Server 2008》)

112152469.png


(2)数据行(data row)

  数据行紧跟在标头之后,数据行的最大长度是8060字节。 由于数据库不能“跨页”,因此单行数据最多8060字节,但对于可变长对象与LOB对象有特殊的处理方法从而可以“跨页”。

  注意:每一行的数据内容最多不能超过8053,因为SQL Server还需要对每一行的数据最少附加7字节的系统数据。


(3)行偏移矩阵(row offsets)

  页的末尾是行偏移矩阵,又译为行偏移数组,或行指针,它最少占用36字节。

  每一数据行都对应一个条目块(Entity Block),每个条目块由2个字节构成,记录该数据行的第一个字节与页首的距离。行偏移矩阵中的条目顺序与数据行的顺序相反,而且只表示了页中数据行的逻辑顺序。注意:行的物理位置可以是页面上的任意位置。如果是聚集表,行偏移矩阵的slot0引用聚集索引键顺序中的第一行,slot1引用第二行,依此类推。

  行偏移矩阵最少为36字节,因此默认最多只可以记录18个数据行。当数据行超过18行时,系统将动态调整数据行占用的字节数与行偏移矩阵占用的字节数,注意:数据行与行偏移矩阵总共是8096字节。


3、行数据存储结构

(1) 数据行的限制

  在旧版本的SQL Server中,行不能跨页,而且被限制为8060字节(Text、Image类型的LOB除外),还要考虑留有足够的空间存储行偏移矩阵的条目块。

(2)行溢出数据(row-overflow data)

  SQL Server 2005新行性,对于含有VarChar(旧版本为text)、NVarchar(旧版本为ntext)、VarBinary(旧版本为image)、SQL_Variant、CLR用户定义类型的数据行,可以超过这一限制。当行超过8060字节时,这些类型的值将被移动到一个“行溢出分配单元”的页中,而在原始页中保留一个24字节的指针,指向行外的数据。这样,行可以跨页,但行内数据仍然被限制为8060字节。

  当这些数据的大小不超过8000字节时,它们的值将被移动到行溢出页中。如果数据的大小超过了8000字节,这些值将被内部处理为一个LOB(large object),而在原始行上维护一个16字节的指针,指向该LOB。


4、行数据的存储类型

  SQL Server有3种存储类型:

(1)行内数据(IN_ROW_DATA)的页面

(2)行溢出数据(ROW_OVERFLOW_DATA)的页面

(3)LOB数据(LOB_DATA)的页面


二、区(Extend)

1、基本概念

  区,也译为扩展,或盘区,是8个物理上连续的页组成的单元,即64KB的空间,用于存储表和索引。 SQL Server 2008有两种类型的区:

(1)统一区。由单个对象拥有,只有该对象可以使用该区中的8个页面。当表或索引需要更多的空间以存储数据时,SQL Server为对象分配一个完整的区。

(2)混合区。每个页面可由一个对象拥有,因此一个混合区最多可由8个对象拥有。对于包含少量数据的对象且不足64KB时,当它需要更多空间时,SQL Server通常只分配一个单独的页,而不是整个区。这个页可以位于一个混合区内。

  由于I/O负载多数消耗在磁盘寻址方面,因此读取一个连续8个页面的区,与读取一个页,所用的时间几乎一样多。SQL Server对一些大型表或索引的扫描,可以在区级别上读取数据。


2、区的分配记录

  SQL Server用两种特殊的页面记录已经分配了哪些区,以及区可以用于哪些类型(混合或统一)。

(1)全局分配映射(GAM)页面

  记录了可以分配给任何用途的区。GAM对它所涵盖的每个区都有一个位(bit),以0表示正在使用中,以1表示可用。每个GAM页面,除去头文件等,有8000字节(64000位)可用。因此每个GAM页可以涵盖64000个区,即4GB。

  GAM总是任何数据库文件的第3个页面(Page ID=2),这个页面之后,每511230个页面就会有一个GAM页面。

(2)共享全局分配映射(SGAM)页面

  记录了用作混合区的区,并且这些区中至少有一个未使用的页。结构与GAM类似,每个区都有一个位,以1表示是混合区并且可用,以0表示没有用作混合区或页面都已被使用。对于这个区,GAM对应的位的值总是为0。每个SGAM页可以涵盖64000个区,即4GB。

  SGAM总是任何数据库文件的第4个页面(Page ID=3),这个页面之后,每511230个页面就会有一个SGAM页面。

  当对表进行Drop或Truncate时,将释放整个区(将GAM位设置为1,将SGAM位设置为0),这样会使日志记录最小。


3、分配新的区

  如果SQL Server需要找到新的、完全未使用的区,它可以从GAM页中找到值为1的位。

  如果SQL Server需要找到包含可用空间的混合区(有一个或多个可用的页面),则它在SGAM中寻找值为1 的位。如果没有找到具有可用的页的混合区,SQL Server会使用GAM页找到一个全新的区,将它分配为混合区,然后使用其中一个页。如果根本没有可用的区,说明文件已经满了。


、索引分配映射(IAM)

  IAM页面记录表或索引使用的区,它包括3种分配单元(即:行数据的3种存储类型)之一的页面。单个IAM页面只包括单个文件的4GB的区的分配信息,如果表或索引的分区使用了多个文件,就会有多个IAM页面。 例如:具有3种存储类型(行中存储、行溢出和LOB)的4个分区,每个分区都有2个小于4GB文件,那么将有24个IAM页面。如果数据库文件超过4GB,就会有额外的IAM。

  每个IAM是按对象的需要进行分配的,且在数据库文件中随意放置。每个IAM页面都包含一个指针,指向链中的下一个IAM页面。


四、PFS

  页可用空间(PFS)页面记录每页的分配状态,将区分配给对象后,数据库引擎 将使用PFS页来记录区中的哪些页已分配或哪些页可用。PFS 对每页都有一个字节,记录该页是否已分配。如果已分配,则记录该页是为空、已满 1% 到 50%、已满 51% 到 80%、已满 81% 到 95% 还是已满 96% 到 100%。


五、DCM与BCM

  DCM(差分更改映射)和BCM(批量更改映射)页面与GAM和SGAM页面类似,其中有一个位对应于它们所代表的数据库文件中的每个区。它们以固定间隔出现,每隔511230页出现一次。


本文出自 “我们一起追过的MSSQL” 博客,转载请与作者联系!

你可能感兴趣的:(sql,页)