O SQL Server 2022 introduziu a inicialização instantânea de arquivo para eventos de crescimento de arquivo de log de transações. Na página O que há de novo em 2022 , a Microsoft observa:
Em geral, os arquivos de log de transação não podem se beneficiar da inicialização instantânea de arquivo (IFI). A partir do SQL Server 2022 (16.x) (todas as edições) e no Banco de Dados SQL do Azure, a inicialização instantânea de arquivo pode beneficiar eventos de crescimento de log de transação de até 64 MB. O incremento de tamanho de crescimento automático padrão para novos bancos de dados é de 64 MB. Os eventos de crescimento automático do arquivo de log de transações maiores que 64 MB não podem se beneficiar da inicialização instantânea do arquivo.
Para testar isso, tentei aumentar repetidamente o arquivo de log em tamanhos diferentes (digamos, 50 e 70 MB), mas ... nenhum deles foi instantâneo.
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
Tentei 63 MB, 65 MB e não pareceu fazer muita diferença - os testes levaram cerca de 15 a 16 segundos para 100 eventos de crescimento.
Portanto, a questão é: a inicialização instantânea de arquivo simplesmente não funciona para crescimentos manuais de arquivos de log, mesmo em tamanhos pequenos? Apenas eventos de autocrescimento? (Ainda não consegui provar que funciona para eventos de autocrescimento.)
Sim.
Eu tentei o seguinte no SQL Server 2019 e SQL Server 2022 (com IFI habilitado durante a configuração)
Para o SQL Server 2019, posso ver a totalidade da seção de arquivo recém-alocada sendo gravada em blocos de 8 MB (a partir do comprimento e deslocamento)
A pilha em ProcMon mostra que esta atividade está acontecendo ao zerar o arquivo
Não existe tal seção correspondente em 2022
O tempo decorrido entre a primeira e a última entrada de procmon foi de 46 ms no caso de 2019 (21:30:54,8866621 a 21:30:54,9330198) e 7,9 ms no caso de 2022 (21:31:54,8078691 a 21:31:54,8157769).
SET STATISTICS TIME ON
Também vi diferenças de tempo semelhantes relatadas por meio da saída.ambos estavam gravando no mesmo disco de laptop (no qual os olhos de águia podem notar acima, eu acidentalmente chamei minha instância 2022 de 20222).
Eu estava interessado em saber por que o loop funcionou tão mal. Parece que apenas a primeira entrada realmente se beneficia do IFI.
Quando eu adiciono o seguinte ao meu código acima ...
O segundo crescimento leva muito mais tempo e grava em muito mais arquivos (incluindo a seção que não foi inicializada anteriormente)
Isso não se deve ao zeramento do arquivo, mas também não é algo que vejo em minha instância do SQL Server 2019, portanto, parece ser um trabalho adicional que pode ou não estar relacionado a esse recurso.
Irritantemente, por algum motivo, o ProcMon apenas me mostra uma guia em branco em vez das pilhas de chamadas para o WriteFile destacado, mas o gravador de desempenho do Windows implicaria que isso é gasto
sqlmin.dll!SQLServerLogMgr::FormatVirtualLogFile
(o que está de acordo com a resposta de Paul)Confirmado na minha instância local 2022 usando:
Saída dos sinalizadores de rastreamento global 3004 (mostrar detalhes de inicialização instantânea do arquivo) e 1810 (detalhes do evento de crescimento) com 3604 também habilitado para direcionar a saída para a guia de mensagens do SSMS:
O sinalizador de rastreamento 1810 tem um bug em sua string de formato (
%l64d
em vez de%I64d
). Se você não corrigir isso sozinho, poderá monitorar o crescimento usando os eventos estendidosdatabase_file_size_change
oumodify_file_operation
em vez disso. Não há nenhum evento para monitorar IFI, tanto quanto eu sei, então você precisará de 3004 para essa parte.sys.dm_db_log_info
antes dos crescimentos de log:e depois:
Observe que cada crescimento adicionou um único arquivo de log virtual (VLF).
O novo recurso pode ser desativado com o sinalizador de rastreamento global 1837. Com esse conjunto, a saída muda para:
Redefinindo para o mesmo ponto de partida e executando o script dez growth novamente, o log DMV mostra:
Observe que a maioria dos crescimentos de 64 MB resultou em VLFs de 4 x 16 MB.