SQL Server 如何找到第一个 IAM 页

Bei*_*DBA 3 sql-server

今天,出于好奇,我在新数据库中第一次分配新表时检查日志。 数据库的 fn_db_log

我可以看到 GAM 用于查找空闲范围,然后从该范围中分配一个页面用作数据页。第 8-12 行。

然后它分配另一个页面,该页面不是来自之前使用的范围,并将此页面用作 IAM。第 13-16 行。

我的问题是,SQL Server 从何处找到此页面并将其设为 IAM。为什么这个页面不是从 GAM 访问的范围分配的。

Ran*_*gen 10

我可以看到 GAM 用于查找空闲范围,然后从该范围中分配一个页面用作数据页。第 8-12 行。

在您的事务日志文件中看到的这种范围分配是您的分配单元的统一范围分配。

然后它分配另一个页面,该页面不是来自之前使用的范围,并将此页面用作 IAM。第 13-16 行。

在您的事务日志文件中看到的这个页面分配是一个属于混合区的页面,正如您所指出的,这个页面由您的 IAM 页面使用。

SQL Server 从何处找到此页面并将其设为 IAM。为什么这个页面不是从 GAM 访问的范围分配的。

混合区

IAM 页始终是混合区的一部分。

Paul S. Randal 关于 IAM 页面始终是混合区的一部分的证明:

存储引擎内部:IAM 页面、IAM 链和分配单元

关于 IAM 页面还有几点需要注意:

有来自混合区的单页分配,并且不会在任何地方被跟踪

Paul S. Randal 的另一篇文章:

存储引擎内部:范围剖析

混合区(SQL Server 2016 以后)

默认情况下禁用混合盘区的使用,唯一的混合页面是 IAM 页面,并且无法禁用。


IAM 页面是如何分配的

页面和范围架构指南中

IAM 页根据每个分配单元的需要进行分配,并随机位于文件中。系统视图 sys.system_internals_allocation_units 指向分配单元的第一个 IAM 页。该分配单元的所有 IAM 页面都链接在一个链中。

IAM 页随机位于文件中,但按分配单元链接在一起。


取决于版本和跟踪标志 1118

有了这些信息,并且知道 pre sql server 2016(没有 TF 1118)表可以为分配的前 8 个页面获得混合扩展区,一个扩展区实际上可以同时包含 IAM 页和数据页。

在前面提到的文章中再次证明:存储引擎内部:范围剖析

这意味着混合区也可能包含多种页面类型,包括 IAM、数据、索引或文本页面。

默认情况下,从 SQL Server 2016(或启用 TF 1118)开始,数据页将成为统一范围的一部分,而 IAM 页将成为不同的混合范围的一部分。

这应该可以解释为什么您的 IAM 页面的映射方式与您的数据页面不同,并且分配的范围是统一的。


测试混合区分配

在没有 TF 1118 的 SQL Server 2012 实例上创建一些测试表并为每个表插入一行。

CREATE TABLE dbo.IAM1(id int)
INSERT INTO dbo.IAM1(id)
VALUES(1); -- IAM2,IAM3,IAM4, ... tables created
Run Code Online (Sandbox Code Playgroud)

然后我们可以使用DBCC IND映射这些分配的统一页面,在我端的 150 - 180 范围内。

如果我们然后检查仅分配了一个 SGAM 页面的数据库的 SGAM 设置,在页面 id 3 上:

DBCC TRACEON (3604);
DBCC PAGE ('database', 1, 3, 3);
Run Code Online (Sandbox Code Playgroud)

我们为我们的页面范围获取此信息

(1:152)      - (1:168)      = NOT ALLOCATED       --> 2 FULL uniform extents                       
(1:176)      -              =     ALLOCATED                              
(1:184)      - (1:256)      = NOT ALLOCATED  
Run Code Online (Sandbox Code Playgroud)

我们看到从 152 到 168 的两个统一范围已满。

然后我们可以检查 PFS 以查看这些是否是 IAM 页面。

DBCC TRACEON (3604);
GO
DBCC PAGE ('database', 1,1, 3);
Run Code Online (Sandbox Code Playgroud)

这是结果

(1:152)      -              =     ALLOCATED   0_PCT_FULL           IAM Page  Mixed Ext
(1:153)      -              =     ALLOCATED   0_PCT_FULL                     Mixed Ext
(1:154)      -              =     ALLOCATED   0_PCT_FULL           IAM Page  Mixed Ext
(1:155)      -              =     ALLOCATED   0_PCT_FULL                     Mixed Ext
(1:156)      - (1:157)      =     ALLOCATED   0_PCT_FULL           IAM Page  Mixed Ext
(1:158)      - (1:162)      =     ALLOCATED   0_PCT_FULL                     Mixed Ext
(1:163)      -              =     ALLOCATED  50_PCT_FULL                     Mixed Ext
(1:164)      -              =     ALLOCATED   0_PCT_FULL           IAM Page  Mixed Ext
Run Code Online (Sandbox Code Playgroud)

5 个 IAM 页,不足以获得仅 IAM 页的完整统一范围。使用其中一张表的一页数据:

(1:163)      -              =     ALLOCATED  50_PCT_FULL                     Mixed Ext
Run Code Online (Sandbox Code Playgroud)

和 10 个系统数据页。

当通过读取事务日志文件使用统一扩展区时,您还将看到这些单页分配:

Operation               AllocUnitName           Description
LOP_FORMAT_PAGE         dbo.IAM3    
LOP_BEGIN_XACT          NULL                    AllocFirstPage;0x0105000000000005150000002204bf2bf6b1f23aeef85d6e8f150100
LOP_MODIFY_ROW          dbo.IAM3                Allocated 0001:00000076
LOP_MODIFY_ROW          Unknown Alloc Unit      Allocated 0001:00000077
LOP_FORMAT_PAGE         dbo.IAM3    
LOP_HOBT_DELTA          NULL                    Action 0 (HOBT_PAGE_COUNT) on rowset 72057594039173120. Leaf page delta: 0, Reserved page delta: 1, Used page delta: 1
LOP_MODIFY_ROW          dbo.IAM3    
LOP_CREATE_ALLOCCHAIN   NULL    
LOP_LOCK_XACT           NULL    
LOP_COMMIT_XACT         NULL    
Run Code Online (Sandbox Code Playgroud)

编辑

感谢您的回复,但我的问题是 SQL Server 如何为 IAM 决定页面 0001:00000135。它应该在 GAM 或 SGAM 甚至 PFS 中的某处查看可用空间检查,但它没有。我多次创建了一个新数据库和一个新表。并发现第一个 IAM 页面总是相同的,也是相同的数据页面

IAM / 混合页面分配

下面的引用解释了使用混合页面时的 tempdb 争用应该具有相同的用户数据库应用程序和 IAM 页面分配。

当 SQL Server 搜索要分配的混合页面时,它总是在同一文件和 SGAM 页面上开始扫描。当多个混合页面分配正在进行时,这会导致 SGAM 页面上的激烈争用。这可能会导致“症状”部分中记录的问题。

来源

如果我错了,请纠正我,但它用于分配 IAM 页面的机制是检查SGAM页面以获取具有空闲页面的混合范围(SGAM 位 = 1),然后使用该PFS页面查找第一个未分配的混合范围页面到分配 IAM 页。

(如果有空闲页的混合区,如果没有,它也必须搜索 GAM 页)。

该声明基于以下理解:分配新的 IAM 页应该与分配新的混合区数据页相同。

管理对象使用的空间

对于每个范围,SQL Server 数据库引擎搜索 PFS 页面以查看是否存在可以使用的页面

Paul S. Randal 为什么 PFS 页面无法修复

答案是,is-this-page-allocated-or-not 信息不会在数据库中的任何其他地方复制,并且在所有情况下都无法重建它。

管理范围分配

为了查找具有空闲页的混合区,SQL Server 数据库引擎在 SGAM 中搜索 1 位。

为了分配混合区,SQL Server 数据库引擎在 GAM 中搜索 1 位,将其设置为 0,然后还将 SGAM 中的相应位设置为 1。