> 文章列表 > SQL Server的页面(pages )和盘区(extents)体系结构

SQL Server的页面(pages )和盘区(extents)体系结构

SQL Server的页面(pages )和盘区(extents)体系结构

pages 和 extents 体系结构

  • 一、背景
  • 二、页面和盘区
    • 2.1、页面
    • 2.2、大行支持
    • 2.3、行溢出注意事项
    • 2.4、盘区(extents)
  • 三、管理扩展数据分配和可用空间
    • 3.1、管理扩展数据块分配
    • 3.2、跟踪可用空间
  • 四、管理对象使用的空间
  • 五、追踪修改后的盘区
  • 总结

一、背景

页面是 SQL Server 中数据存储的基本单元。范围是八个物理上连续页面的集合。盘区有助于有效地管理页面。了解页面和盘区的体系结构对于设计和开发高效执行的数据库非常重要。

二、页面和盘区

SQL Server 中数据存储的基本单位是页面。分配给数据库中数据文件(.mdf 或 .ndf)的磁盘空间在逻辑上分为从 0 到 n 连续编号的页。磁盘 I/O 操作在页面级别执行。也就是说,SQL Server 读取或写入整个数据页。

扩展数据块是八个物理上连续的页面的集合,用于有效地管理页面。所有页面都组织到盘区中。

2.1、页面

在普通书籍中,所有内容都写在页面上。与书籍类似,SQL Server 将所有数据行写入页面上,并且所有数据页的大小相同:8 KB。在图书中,大多数页面包含数据(书籍的主要内容),而某些页面包含有关内容的元数据(例如,目录和索引)。同样,SQL Server 也不例外:大多数页面都包含用户存储的实际数据行;这些称为数据页和文本/图像页(对于特殊情况)。索引页包含有关数据所在位置的索引引用。最后,还有一些系统页面存储有关数据组织的各种元数据。

每个页面都以一个 96 字节的标头开头,该标头用于存储有关页面的系统信息。此信息包括页码、页面类型、页面上的可用空间量以及拥有页面的对象的分配单元 ID。

下表显示了 SQL Server 数据库的数据文件中使用的页类型。

页面类型 内容
数据 包含除文本、ntext、图像、nvarchar(max)、varchar(max)、varbinary(max) 和 xml 数据(行中的文本设置为 ON 时)之外的所有数据的数据行。
指数 索引条目。
文本/图像 大型对象数据类型:text、ntext、image、nvarchar(max)、varchar(max)、varbinary(max) 和 xml 数据。当数据行超过 8 KB 时,可变长度列:varchar、nvarchar、varbinary 和 sql_variant。
全局分配映射 (GAM)共享全局分配映射 (SGAM) 有关是否分配盘区的信息。
页面可用空间 (PFS) 有关页面分配和页面上可用空间的信息。
索引分配图 (IAM) 有关每个分配单元的表或索引使用的盘区的信息。
批量更改映射 (BCM) 有关自上次每个分配单元的备份日志语句以来由批量操作修改的扩展数据块的信息。
差分更改映射 (DCM) 有关自上次每个分配单元的备份数据库语句以来已更改的扩展数据块的信息。

数据行以串行方式存储在页面上,紧跟在标题之后开始。行偏移表从页面末尾开始,每个行偏移表包含页面上每一行的一个条目。每个行偏移量条目存储行的第一个字节与页面开头的距离。因此,行偏移量表的功能是帮助 SQL Server 快速定位页面上的行。行偏移表中的条目与页面上的行顺序相反。

SQL Server的页面(pages )和盘区(extents)体系结构

2.2、大行支持

行不能跨页面;但是,行的某些部分可能会移出行的页面,因此行可能非常大。页面上单行中包含的最大数据和开销为 8,060 字节。这不包括存储在文本/图像页面类型中的数据。

对于包含 varchar、nvarchar、varbinary 或 sql_variant 列的表,此限制放宽。当表中所有固定列和可变列的总行大小超过 8,060 字节的限制时,SQL Server 会将一个或多个可变长度列动态移动到ROW_OVERFLOW_DATA分配单元中的页,从宽度最大的列开始。

每当插入或更新操作使行的总大小超过 8,060 字节限制时,就会执行此操作。将列移动到ROW_OVERFLOW_DATA分配单元中的页面时,将保留IN_ROW_DATA分配单元中原始页面上的 24 字节指针。如果后续操作减小了行大小,SQL Server 会将列动态移回原始数据页。

2.3、行溢出注意事项

一行不能驻留在多个页面上,如果可变长度数据类型字段的组合大小超过 8060 字节限制,则行可能会溢出。为了说明,可以创建一个包含两列的表:一列 varchar(7000) 和另一列 varchar (2000)。单独两列都不超过 8060 字节,但如果填充每列的整个宽度,它们可以组合在一起。SQL Server 可能会动态地将 varchar(7000) 可变长度列移动到ROW_OVERFLOW_DATA分配单元中的页。组合每行超过 8,060 字节的 varchar、nvarchar、varbinary 或 sql_variant 或 CLR 用户定义类型列时,请考虑以下事项:

  • 随着记录根据更新操作而延长,将大型记录移动到另一页会动态发生。缩短记录的更新操作可能会导致记录移回IN_ROW_DATA分配单元中的原始页面。
    查询和执行其他选择操作(如对包含行溢出数据的大型记录进行排序或联接)会减慢处理时间,因为这些记录是同步处理的,而不是异步处理的。
    因此,在设计包含多个 varchar、nvarchar、varbinary 或 sql_variant 或 CLR 用户定义类型列的表时,请考虑可能流过的行的百分比以及可能查询此溢出数据的频率。如果可能对许多行溢出数据进行频繁查询,请考虑规范化表,以便将某些列移动到另一个表。然后,可以在异步 JOIN 操作中查询此内容。

  • 对于 varchar、nvarchar、varbinary 或 sql_variant 以及 CLR 用户定义类型列,各个列的长度仍必须在 8,000 字节的限制范围内。只有它们的组合长度才能超过表的 8,060 字节行限制。

  • 其他数据类型列(包括 char 和 nchar 数据)的总和必须在 8,060 字节的行限制范围内。大型对象数据也不受 8,060 字节行限制的限制。

  • 聚集索引的索引键不能包含ROW_OVERFLOW_DATA分配单元中具有现有数据的 varchar 列。如果在 varchar 列上创建了聚集索引,并且现有数据位于IN_ROW_DATA分配单元中,则对该列执行后续插入或更新操作(会将数据推送到行外)将失败。

  • 可以将包含行溢出数据的列作为非聚集索引的键列或非键列包括在内。

  • 使用稀疏列的表的记录大小限制为 8,018 字节。当转换后的数据加上现有记录数据超过 8,018 字节时,将返回 MSSQLSERVER 错误 576。在稀疏类型和非稀疏类型之间转换列时,数据库引擎将保留当前记录数据的副本。这会暂时使记录所需的存储空间加倍。

  • 要获取可能包含行溢出数据的表或索引的信息,请使用sys.dm_db_index_physical_stats动态管理功能。

2.4、盘区(extents)

盘区是管理空间的基本单位。扩展数据块是八个物理上连续的页面,即 64 KB。这意味着 SQL Server 数据库每兆字节有 16 个扩展数据块。

SQL Server 有两种类型的扩展数据块:

  • 统一扩展数据块由单个对象拥有;范围中的所有八个页面只能由所属对象使用。
  • 混合盘区最多可由八个对象共享。范围中的八个页面中的每一个都可以由不同的对象拥有。

SQL Server的页面(pages )和盘区(extents)体系结构

三、管理扩展数据块分配和可用空间

管理扩展数据块分配和跟踪可用空间的 SQL Server 数据结构具有相对简单的结构。这有以下好处:

  • 可用空间信息密集,因此包含此信息的页面相对较少。这通过减少检索分配信息所需的磁盘读取次数来提高速度。这也增加了分配页保留在内存中并且不需要更多读取的可能性。

  • 大多数分配信息未链接在一起。这简化了分配信息的维护。可以快速执行每个页面分配或取消分配。这减少了必须分配或取消分配页面的并发任务之间的争用。

3.1、管理扩展数据块分配

SQL Server 使用两种类型的分配映射来记录盘区的分配:

  • Global Allocation Map (GAM)。GAM 页面记录已分配的盘区。每个 GAM 涵盖 64,000 个盘区,或近 4 千兆字节 (GB) 的数据。GAM 在其覆盖的间隔中的每个扩展数据块都有 1 位。

  • Shared Global Allocation Map (SGAM)。SGAM 页面记录当前用作混合盘区的盘区,并且至少有一个未使用的页面。每个 SGAM 涵盖 64,000 个盘区,或近 4 GB 的数据。SGAM 在其覆盖的间隔内具有 1 个扩展数据块。

每个扩展数据块根据其当前使用情况在 GAM 和 SGAM 中设置了以下位模式。

范围的当前使用情况 GAM 位设置 SGAM位设置
免费,未被使用 1 0
均匀范围或完全混合范围 0 0
具有免费页面的混合范围 0 1

这会导致简单的范围管理算法。

  • 为了分配统一的扩展数据块,数据库引擎会在 GAM 中搜索一个位,并将其设置为10。
  • 若要查找具有空闲页的混合盘区,数据库引擎会在 SGAM 中搜索一点。
  • 若要分配混合盘区,数据库引擎会在 GAM 中搜索一个位,将其设置为 ,然后将 SGAM 中的相应位设置为101 。
  • 若要解除分配扩展数据块,数据库引擎应确保将 GAM 位设置为 ,并将 SGAM 位设置为10 。

数据库引擎内部使用的算法比本文中所述的算法更复杂,因为数据库引擎在数据库中均匀分布数据。但是,即使是真正的算法也可以通过不必管理扩展数据块分配信息链来简化。

3.2、跟踪可用空间

页面可用空间 (PFS) 页面记录每个页面的分配状态、是否已分配单个页面以及每个页面上的可用空间量。PFS 每页有 1 个字节,记录页面是否已分配,如果是,则记录页面是否为空、1% 到 50% 已满、51% 到 80% 已满、81% 到 95% 已满或 96% 到 100% 已满。

将扩展数据块分配给对象后,数据库引擎将使用 PFS 页记录盘区中的哪些页已分配或可用。当数据库引擎必须分配新页时,将使用此信息。页面中的可用空间量仅针对堆和文本/图像页面进行维护。当数据库引擎必须查找具有可用空间来保存新插入的行的页时,将使用它。索引不需要跟踪页面可用空间,因为插入新行的点由索引键值设置。

数据文件中会为其跟踪的每个附加范围添加新的 PFS、GAM 或 SGAM 页面。因此,在第一个 PFS 页面之后有一个新的 PFS 页面 8,088 页,在随后的 8,088 页间隔中存在额外的 PFS 页面。为了说明,页面 ID 1 是 PFS 页面,页面 ID 8088 是 PFS 页面,页面 ID 16176 是 PFS 页面,依此类推。

在第一个 GAM 页面之后有一个新的 GAM 页面 64,000 个盘区,它会跟踪其后的 64,000 个盘区;序列以 64,000 个程度的间隔继续。同样,在第一个 SGAM 页面之后有一个新的 SGAM 页面 64,000 个盘区,在随后的 64,000 个盘区间隔中还有其他 SGAM 页面。

下图显示了数据库引擎用于分配和管理盘区的页序列。
SQL Server的页面(pages )和盘区(extents)体系结构

四、管理对象使用的空间

索引分配映射 (IAM) 页面映射分配单元使用的数据库文件的 4 GB 部分中的扩展数据块。分配单位是以下三种类型之一:

  • IN_ROW_DATA:保存堆或索引的分区。
  • LOB_DATA:保存大型对象 (LOB) 数据类型,如 xml、varbinary(max) 和 varchar(max)。
  • ROW_OVERFLOW_DATA:保存存储在超过 8,060 字节行大小限制的 varchar、nvarchar、varbinary 或 sql_variant 列中的可变长度数据。

堆或索引的每个分区至少包含一个IN_ROW_DATA分配单元。它还可能包含LOB_DATA或ROW_OVERFLOW_DATA分配单元,具体取决于堆或索引架构。

IAM 页面涵盖文件中的 4 GB 范围,与 GAM 或 SGAM 页面的覆盖范围相同。如果分配单元包含来自多个文件的扩展数据块,或者一个文件的多个 4 GB 范围,则 IAM 链中将链接多个 IAM 页面。因此,每个分配单元对于其具有扩展数据块的每个文件至少有一个 IAM 页面。如果分配给分配单位的文件上的扩展数据块范围超过单个 IAM 页面可以记录的范围,则文件上也可能有多个 IAM 页面。
SQL Server的页面(pages )和盘区(extents)体系结构
IAM 页面根据每个分配单元的要求进行分配,并随机位于文件中。系统视图指向分配单位的第一个 IAM 页面。该分配单元的所有 IAM 页面都链接在 IAM 链中。
SQL Server的页面(pages )和盘区(extents)体系结构
IAM 页面具有一个标题,指示 IAM 页面映射的范围范围的起始范围。IAM 页面还具有一个大位图,其中每个位表示一个扩展数据块。地图中的第一个位表示范围中的第一个范围,第二个位表示第二个范围,依此类推。如果位为 ,则它所表示的范围不会分配给拥有 IAM 的分配单元。如果位为 ,则它所表示的范围将分配给拥有 IAM 页面的分配单元。

当数据库引擎必须插入新行并且当前页中没有可用空间时,它会使用 IAM 和 PFS 页查找要分配的页,或者对于堆或文本/图像页,查找具有足够空间来保存该行的页。数据库引擎使用 IAM 页查找分配给分配单元的盘区。对于每个盘区,数据库引擎都会搜索 PFS 页,以查看是否有可以使用的页。每个 IAM 和 PFS 页面都涵盖许多数据页面,因此数据库中的 IAM 和 PFS 页面很少。这意味着 IAM 和 PFS 页面通常位于 SQL Server 缓冲池的内存中,因此可以快速搜索它们。对于索引,新行的插入点由索引键设置,但是当需要新页面时,将发生前面描述的过程。

仅当数据库引擎无法在现有扩展数据块中快速找到具有足够空间来容纳要插入的行的页面时,它才会将新扩展数据块分配给分配单元。

数据库引擎使用比例填充分配算法从文件组中可用的盘区中分配盘区。在包含两个文件的同一文件组中,如果一个文件的可用空间是另一个文件的两倍,则将从文件中分配两页,其中从另一个文件分配的每一页都有可用空间。这意味着文件组中的每个文件都应具有相似的已用空间百分比。

五、追踪修改后的盘区

SQL Server 使用两种内部数据结构来跟踪由大容量复制操作修改的盘区,以及自上次完整备份以来修改的盘区。这些数据结构大大加快了差异备份的速度。当数据库使用大容量日志恢复模式时,它们还可以加快大容量复制操作的日志记录。与 GAM 和 SGAM 页面一样,这些结构是位图,其中每个位表示单个扩展数据块。

  • 差分更改映射 (DCM):这将跟踪自上次语句以来已更改的范围。差异备份仅读取 DCM 页以确定修改了哪些盘区。这大大减少了差异备份必须扫描的页数。差异备份运行的时间长度与自上一条语句以来修改的扩展数据块数成正比,而不是与数据库的总体大小成正比。

  • 批量更改映射 (BCM):这将跟踪自上一条语句以来被大容量日志操作修改的盘区。尽管 BCM 页显示在所有数据库中,但仅当数据库使用大容量日志恢复模式时,它们才相关。

DCM 页面和 BCM 页面之间的间隔与 GAM 和 SGAM 页面之间的间隔相同,为 64,000 个盘区。DCM 和 BCM 页面位于物理文件中的 GAM 和 SGAM 页面后面,如下所示:

SQL Server的页面(pages )和盘区(extents)体系结构

总结

  1. 日志文件不包含页面。它们包含一系列没有固定大小的日志记录。
  2. 系统功能未记录在案,可能会发生变化。不保证兼容性。
  3. 系统视图仅供内部使用,可能会发生变化。不保证兼容性。