Bre*_*zar 7 sql-server transaction-log sql-server-2022
SQL Server 2022 引入了针对事务日志文件增长事件的即时文件初始化。在2022 年新增功能页面中,微软指出:
一般来说,事务日志文件无法从即时文件初始化 (IFI) 中受益。从 SQL Server 2022 (16.x)(所有版本)和 Azure SQL 数据库开始,即时文件初始化可以使事务日志增长事件受益最多 64 MB。新数据库的默认自动增长大小增量为 64 MB。大于 64 MB 的事务日志文件自动增长事件无法从即时文件初始化中受益。
为了测试这一点,我尝试反复以不同大小(例如 50 和 70MB)增长日志文件,但是......它们都不是瞬时的。
DROP DATABASE LogGrowthTest;
GO
CREATE DATABASE [LogGrowthTest]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'LogGrowthTest', FILENAME = N'Z:\MSSQL\Data\LogGrowthTest.mdf',
SIZE = 8192KB , FILEGROWTH = 60000KB )
LOG ON
( NAME = N'LogGrowthTest_log', FILENAME = N'Z:\MSSQL\Data\LogGrowthTest_log.ldf' ,
SIZE = 8192KB , FILEGROWTH = 60000KB )
GO
DECLARE @TestStartTime DATETIME2 = GETDATE(), @i INT = 1,
@StringStarter NVARCHAR(4000) = N'ALTER DATABASE [LogGrowthTest] MODIFY FILE ( NAME = N''LogGrowthTest_log'', SIZE = ',
@StringToExec NVARCHAR(4000);
WHILE @i < 101
BEGIN
/* CHANGE THE 63 IN THE BELOW LINE TO CHANGE FILE GROWTH SIZE: */
SET @StringToExec = @StringStarter + CAST((@i * 63) AS NVARCHAR(10)) + N'MB );';
PRINT(@StringToExec)
EXEC(@StringToExec);
SET @i = @i + 1;
END
SELECT DATEDIFF(millisecond,@TestStartTime, GETDATE()) AS TestDurationSeconds
GO
Run Code Online (Sandbox Code Playgroud)
我尝试了 63MB、65MB,似乎没有太大区别 - 100 个增长事件的测试大约需要 15-16 秒。
所以问题是,即时文件初始化是否不适用于手动日志文件增长,即使是小尺寸?只有自动增长事件吗?(我还无法证明它也适用于自动增长事件。)
即时文件初始化是否适用于手动日志文件增长?
是的,它确实。
我在 SQL Server 2019 和 SQL Server 2022 上尝试了以下操作(在安装过程中启用了 IFI)
CREATE DATABASE [LogGrowthTest]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'LogGrowthTest', FILENAME = N'...LogGrowthTest.mdf' , SIZE = 8MB , FILEGROWTH = 60000KB )
LOG ON
( NAME = N'LogGrowthTest_log', FILENAME = N'...LogGrowthTest_log.ldf' , SIZE = 8MB , FILEGROWTH = 60000KB )
GO
ALTER DATABASE [LogGrowthTest] MODIFY FILE ( NAME = N'LogGrowthTest_log', SIZE = 64MB );
Run Code Online (Sandbox Code Playgroud)
对于 SQL Server 2019,我可以看到整个新分配的文件部分以 8MB 块的形式写入(从长度和偏移量来看)
ProcMon 中的堆栈显示此活动发生在文件清零过程中
2022年无此对应栏目
在 2019 年的情况下,第一个和最后一个 procmon 条目之间经过的时间为 46 毫秒(21:30:54.8866621 到 21:30:54.9330198),在 2022 年的情况下为 7.9 毫秒(21:31:54.8078691 到 21:31:54.8157769)。
我也通过输出看到了类似的时间差异SET STATISTICS TIME ON
。
两者都写入同一个笔记本电脑光盘(眼尖的人可能会注意到上面我不小心将我的 2022 实例命名为 20222)。
我很感兴趣为什么循环表现如此糟糕。看来只有第一个条目真正受益于 IFI。
当我将以下内容添加到上面的代码中时...
ALTER DATABASE [LogGrowthTest] MODIFY FILE ( NAME = N'LogGrowthTest_log', SIZE = 127MB );
Run Code Online (Sandbox Code Playgroud)
第二次增长花费的时间明显更长,并且写入文件的更多内容(包括之前未初始化的部分)
这不是由于将文件清零所致,而且也不是我在 SQL Server 2019 实例中看到的情况,因此似乎是与此功能可能相关或无关的额外工作。
令人烦恼的是,出于某种原因,ProcMon 只是向我显示了一个空白选项卡,而不是突出显示的 WriteFile 的调用堆栈,但 Windows 性能记录器会暗示这是花费在sqlmin.dll!SQLServerLogMgr::FormatVirtualLogFile
(这与 Paul 的答案相关)
使用以下方法在我的本地 2022 年实例上确认:
SET NOCOUNT ON;
DECLARE
@CurrentSize integer,
@i integer = 1,
@SQL nvarchar(max);
SELECT @CurrentSize = DF.size * 8 / 1024
FROM sys.database_files AS DF
WHERE DF.[name] = N'Sandpit_log';
WHILE @i <= 10
BEGIN
SET @SQL = CONCAT
(
N'
ALTER DATABASE Sandpit
MODIFY FILE
(
NAME = N''Sandpit_log'',
SIZE = ',
@CurrentSize + (@i * 64),
N',
FILEGROWTH = 64MB
);'
)
EXECUTE (@SQL);
SET @i += 1;
END;
Run Code Online (Sandbox Code Playgroud)
全局跟踪标志 3004(显示即时文件初始化详细信息)和 1810(增长事件详细信息)的输出以及 3604 还启用了将输出直接输出到 SSMS 消息选项卡:
SET NOCOUNT ON;
DECLARE
@CurrentSize integer,
@i integer = 1,
@SQL nvarchar(max);
SELECT @CurrentSize = DF.size * 8 / 1024
FROM sys.database_files AS DF
WHERE DF.[name] = N'Sandpit_log';
WHILE @i <= 10
BEGIN
SET @SQL = CONCAT
(
N'
ALTER DATABASE Sandpit
MODIFY FILE
(
NAME = N''Sandpit_log'',
SIZE = ',
@CurrentSize + (@i * 64),
N',
FILEGROWTH = 64MB
);'
)
EXECUTE (@SQL);
SET @i += 1;
END;
Run Code Online (Sandbox Code Playgroud)
%l64d
跟踪标志 1810 在其格式字符串(而不是)中存在错误%I64d
。如果您自己不解决这个问题,您可以使用扩展事件来监控database_file_size_change
增长modify_file_operation
。据我所知,没有任何事件可以监视 IFI,因此该部分需要 3004。
sys.dm_db_log_info
在日志增长之前:
数据库ID | 文件ID | vlf_开始_偏移量 | vlf_size_mb | vlf_序列号 | vlf_活动 | vlf_状态 | vlf_奇偶校验 | vlf_first_lsn | vlf_create_lsn | vlf_加密器_指纹 |
---|---|---|---|---|---|---|---|---|---|---|
5 | 2 | 8192 | 1.93 | 87 | 0 | 0 | 128 | 00000000:00000000:0000 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 2039808 | 1.93 | 88 | 0 | 0 | 128 | 00000000:00000000:0000 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 4071424 | 1.93 | 89 | 1 | 2 | 128 | 00000059:00000010:0001 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 6103040 | 2.17 | 42 | 0 | 0 | 64 | 00000000:00000000:0000 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 8388608 | 56 | 43 | 0 | 0 | 64 | 00000000:00000000:0000 | 00000027:0000010B:0001 | 无效的 |
然后:
数据库ID | 文件ID | vlf_开始_偏移量 | vlf_size_mb | vlf_序列号 | vlf_活动 | vlf_状态 | vlf_奇偶校验 | vlf_first_lsn | vlf_create_lsn | vlf_加密器_指纹 |
---|---|---|---|---|---|---|---|---|---|---|
5 | 2 | 8192 | 1.93 | 87 | 0 | 0 | 128 | 00000000:00000000:0000 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 2039808 | 1.93 | 88 | 0 | 0 | 128 | 00000000:00000000:0000 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 4071424 | 1.93 | 89 | 1 | 2 | 128 | 00000059:00000010:0001 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 6103040 | 2.17 | 42 | 0 | 0 | 64 | 00000000:00000000:0000 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 8388608 | 56 | 43 | 0 | 0 | 64 | 00000000:00000000:0000 | 00000027:0000010B:0001 | 无效的 |
5 | 2 | 67108864 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000088F:0002 | 无效的 |
5 | 2 | 134217728 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000896:0001 | 无效的 |
5 | 2 | 201326592 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000089D:0001 | 无效的 |
5 | 2 | 268435456 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008A4:0001 | 无效的 |
5 | 2 | 335544320 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008AB:0001 | 无效的 |
5 | 2 | 402653184 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008B2:0001 | 无效的 |
5 | 2 | 469762048 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008B9:0001 | 无效的 |
5 | 2 | 536870912 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008C0:0001 | 无效的 |
5 | 2 | 603979776 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008C7:0001 | 无效的 |
5 | 2 | 671088640 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008CE:0001 | 无效的 |
注意到每个增长都添加了一个虚拟日志文件 (VLF)。
可以使用全局跟踪标志 1837禁用新功能。设置该标志后,输出将更改为:
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 8192 to 16384 (Offset 0x4000000 to 0x8000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 131072 KB).
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 16384 to 24576 (Offset 0x8000000 to 0xc000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 196608 KB).
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 24576 to 32768 (Offset 0xc000000 to 0x10000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 262144 KB).
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 32768 to 40960 (Offset 0x10000000 to 0x14000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 327680 KB).
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 40960 to 49152 (Offset 0x14000000 to 0x18000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 393216 KB).
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 49152 to 57344 (Offset 0x18000000 to 0x1c000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 458752 KB).
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 57344 to 65536 (Offset 0x1c000000 to 0x20000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 524288 KB).
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 65536 to 73728 (Offset 0x20000000 to 0x24000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 589824 KB).
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 73728 to 81920 (Offset 0x24000000 to 0x28000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 655360 KB).
Skip zeroing D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf from page 81920 to 90112 (Offset 0x28000000 to 0x2c000000) 64 mb
Grow the file D:\Databases\MSSQL16.SQL2022\MSSQL\DATA\Sandpit_log.ldf (file_id = 2, auto_grow = 0, growth = 65536 KB, new_size = 720896 KB).
Run Code Online (Sandbox Code Playgroud)
重置到相同的起点并再次运行十增长脚本,日志DMV显示:
数据库ID | 文件ID | vlf_开始_偏移量 | vlf_size_mb | vlf_序列号 | vlf_活动 | vlf_状态 | vlf_奇偶校验 | vlf_first_lsn | vlf_create_lsn | vlf_加密器_指纹 |
---|---|---|---|---|---|---|---|---|---|---|
5 | 2 | 8192 | 1.93 | 87 | 0 | 0 | 128 | 00000000:00000000:0000 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 2039808 | 1.93 | 88 | 0 | 0 | 128 | 00000000:00000000:0000 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 4071424 | 1.93 | 89 | 1 | 2 | 128 | 00000059:00000010:0001 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 6103040 | 2.17 | 42 | 0 | 0 | 64 | 00000000:00000000:0000 | 00000000:00000000:0000 | 无效的 |
5 | 2 | 8388608 | 56 | 43 | 0 | 0 | 64 | 00000000:00000000:0000 | 00000027:0000010B:0001 | 无效的 |
5 | 2 | 67108864 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008F6:0001 | 无效的 |
5 | 2 | 83886080 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008F6:0001 | 无效的 |
5 | 2 | 100663296 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008F6:0001 | 无效的 |
5 | 2 | 117440512 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008F6:0001 | 无效的 |
5 | 2 | 134217728 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008FE:0001 | 无效的 |
5 | 2 | 150994944 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008FE:0001 | 无效的 |
5 | 2 | 167772160 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008FE:0001 | 无效的 |
5 | 2 | 184549376 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:000008FE:0001 | 无效的 |
5 | 2 | 201326592 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000906:0001 | 无效的 |
5 | 2 | 218103808 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000906:0001 | 无效的 |
5 | 2 | 234881024 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000906:0001 | 无效的 |
5 | 2 | 251658240 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000906:0001 | 无效的 |
5 | 2 | 268435456 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000090E:0001 | 无效的 |
5 | 2 | 285212672 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000090E:0001 | 无效的 |
5 | 2 | 301989888 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000090E:0001 | 无效的 |
5 | 2 | 318767104 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000090E:0001 | 无效的 |
5 | 2 | 335544320 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000916:0001 | 无效的 |
5 | 2 | 352321536 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000916:0001 | 无效的 |
5 | 2 | 369098752 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000916:0001 | 无效的 |
5 | 2 | 385875968 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000916:0001 | 无效的 |
5 | 2 | 402653184 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000091E:0001 | 无效的 |
5 | 2 | 419430400 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000091E:0001 | 无效的 |
5 | 2 | 436207616 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000091E:0001 | 无效的 |
5 | 2 | 452984832 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000091E:0001 | 无效的 |
5 | 2 | 469762048 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000926:0001 | 无效的 |
5 | 2 | 486539264 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000926:0001 | 无效的 |
5 | 2 | 503316480 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000926:0001 | 无效的 |
5 | 2 | 520093696 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000926:0001 | 无效的 |
5 | 2 | 536870912 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000092E:0001 | 无效的 |
5 | 2 | 553648128 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000092E:0001 | 无效的 |
5 | 2 | 570425344 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000092E:0001 | 无效的 |
5 | 2 | 587202560 | 16 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000092E:0001 | 无效的 |
5 | 2 | 603979776 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:00000936:0001 | 无效的 |
5 | 2 | 671088640 | 64 | 0 | 0 | 0 | 0 | 00000000:00000000:0000 | 00000059:0000093D:0001 | 无效的 |
请注意,大多数 64MB 增长会导致 4 x 16MB VLF。