在我的测试实验室中试验 VLF 行为。首先,我创建了两个具有不同日志文件大小(1024 和 2048 MO)的数据库(BASE2 和 BASE3):
其次,我正在运行以下查询以确定日志空间使用情况和 VLF 的活动部分:
USE BASE2
dbcc loginfo
GO
USE BASE3
dbcc loginfo
GO
DBCC SQLPERF(LOGSPACE)
所以在我看来,我可以回收很多空间。现在开始此查询以缩小所有数据库日志文件:
DECLARE
@db nvarchar(255),
@fileName nvarchar(255),
@cmd nvarchar(255)
BEGIN
DECLARE dbcursor CURSOR
FOR
SELECT table2.name AS BASE, table1.name AS FICHIER_JOURNAL_BASE
--table1.database_id,
--table1.physical_name,
--table1.type_desc
FROM sys.master_files AS table1
INNER JOIN sys.databases AS table2
ON table1.database_id = table2.database_id
WHERE table1.database_id > 4 AND table1.type_desc = 'LOG'
AND table2.state_desc = 'ONLINE' AND table2.recovery_model_desc = 'FULL';
OPEN dbcursor
FETCH NEXT FROM dbcursor INTO @db, @fileName;
WHILE (@@FETCH_STATUS <> -1)
BEGIN
--print @db;
SET @cmd = 'USE ['+ @db +']; DBCC SHRINKFILE ('''+@fileName+''',512);'
PRINT 'USE ['+ @db +']; DBCC SHRINKFILE ('''+@fileName+''',512);'
EXECUTE (@cmd)
FETCH NEXT FROM dbcursor INTO @db, @fileName;
END
CLOSE dbcursor;
DEALLOCATE dbcursor;
END
结果在这里结束:
请求的值为 512MO,但磁盘上的当前值约为 650MO。如果我重新启动查询
USE [BASE2]; DBCC SHRINKFILE ('BASE2_log',8);
USE [BASE3]; DBCC SHRINKFILE ('BASE3_log',8);
磁盘上的价值将在 250 MO 左右。那么为什么我的第一个查询没有将日志文件缩小到请求的值 512 MO 呢?实际上,文件末尾没有活动的 VLF,而且仍有大量未使用的空间。
根据此文档(部分:缩小日志文件如何工作?):
您有 1GB 和 2GB 的日志文件,相当于 131,072 的 8 和 16 个 vlf。你说缩小到 512MB (524,288kb)。由于这是在 VLF 边界上,因此它会四舍五入到下一个最高 VLF 边界(添加 131,072),即 (655,360kb),这与您看到的磁盘空间分配非常接近。