sys.dm_db_log_info (Transact-SQL)
适用于:SQL Server 2016 SP 2 及更高版本
Azure SQL 数据库
Azure SQL 托管实例
返回虚拟日志文件 (VLF) 事务日志的信息。 请注意,所有事务日志文件都合并在表输出中。 输出中的每一行都表示事务日志中的一个 VLF,并在日志中提供与该 VLF 相关的信息。
语法
sys.dm_db_log_info ( database_id )
自变量
database_id |NULL |默认
数据库的 ID。 database_id 为 int。有效输入是数据库的 ID 号、NULL 或 DEFAULT。 默认值为 NULL。 NULL 和 DEFAULT 是当前数据库上下文中的等效值。
指定 NULL 可返回当前数据库的 VLF 信息。
可以指定内置函数 DB_ID。 使用 DB_ID
但不指定数据库名称时,当前数据库的兼容级别必须为 90 或更高。
返回的表
列名称 | 数据类型 | 说明 |
---|---|---|
database_id | int | 数据库 ID。 |
file_id | smallint | 事务日志的文件 ID。 |
vlf_begin_offset | bigint | 虚拟日志文件 (VLF) 从事务日志文件开头的偏移位置。 |
vlf_size_mb | float | 虚拟日志文件 (VLF) 大小(以 MB 为单位),四舍五入到两位小数。 |
vlf_sequence_number | bigint | 虚拟日志文件 (创建的顺序) 序列号的 VLF 。 用于唯一标识日志文件中的 VLF。 |
vlf_active | bit | 指示虚拟 日志文件 (VLF) 是否正在使用中。 0 - 未使用 VLF。 1 - VLF 处于活动状态。 |
vlf_status | int | 虚拟日志文件的状态 (VLF) 。 可能的值包括 0 - VLF 处于非活动状态 1 - 已初始化 VLF 但未使用 2 - VLF 处于活动状态。 |
vlf_parity | tinyint | 虚拟日志文件 (VLF) 奇偶校验。 在内部用于确定 VLF 中的日志结束。 |
vlf_first_lsn | nvarchar (48) | (VLF ) 虚拟日志文件中第一条日志记录的 LSN ) 的日志序列号 (。 |
vlf_create_lsn | nvarchar (48) | 创建虚拟日志文件的日志序列号 (LSN) (VLF) 。 |
vlf_encryptor_thumbprint | varbinary(20) | 适用于: SQL Server 2019 (15.x) 如果使用 透明数据加密对 VLF 进行加密,则显示 VLF 加密器的指纹,否则 NULL 为 。 |
备注
动态 sys.dm_db_log_info
管理功能替换 DBCC LOGINFO
语句。
SQL Server事务日志体系结构和管理指南中详细介绍了基于增长事件创建的 VLF 数的公式。 从 2022 SQL Server (16.x) 开始,此公式略有变化。
权限
需要 数据库中 VIEW SERVER STATE
的 权限。
SQL Server 2022 及更高版本的权限
需要对数据库具有 VIEW DATABASE PERFORMANCE STATE 权限。
示例
A. 确定具有大量 VLF 的SQL Server实例中的数据库
以下查询确定日志文件中 VLF 数超过 100 的数据库,这可能会影响数据库启动、还原和恢复时间。
SELECT [name], COUNT(l.database_id) AS 'vlf_count'
FROM sys.databases AS s
CROSS APPLY sys.dm_db_log_info(s.database_id) AS l
GROUP BY [name]
HAVING COUNT(l.database_id) > 100;
B. 在收缩日志文件之前确定事务日志中最后一个 VLF
的位置
以下查询可用于确定在事务日志上运行 SHRINK FILE 之前最后一个活动 VLF 的位置,以确定事务日志是否可以收缩。
USE AdventureWorks2016
GO
;WITH cte_vlf AS (
SELECT ROW_NUMBER() OVER(ORDER BY vlf_begin_offset) AS vlfid, DB_NAME(database_id) AS [Database Name], vlf_sequence_number, vlf_active, vlf_begin_offset, vlf_size_mb
FROM sys.dm_db_log_info(DEFAULT)),
cte_vlf_cnt AS (SELECT [Database Name], COUNT(vlf_sequence_number) AS vlf_count,
(SELECT COUNT(vlf_sequence_number) FROM cte_vlf WHERE vlf_active = 0) AS vlf_count_inactive,
(SELECT COUNT(vlf_sequence_number) FROM cte_vlf WHERE vlf_active = 1) AS vlf_count_active,
(SELECT MIN(vlfid) FROM cte_vlf WHERE vlf_active = 1) AS ordinal_min_vlf_active,
(SELECT MIN(vlf_sequence_number) FROM cte_vlf WHERE vlf_active = 1) AS min_vlf_active,
(SELECT MAX(vlfid) FROM cte_vlf WHERE vlf_active = 1) AS ordinal_max_vlf_active,
(SELECT MAX(vlf_sequence_number) FROM cte_vlf WHERE vlf_active = 1) AS max_vlf_active
FROM cte_vlf
GROUP BY [Database Name])
SELECT [Database Name], vlf_count, min_vlf_active, ordinal_min_vlf_active, max_vlf_active, ordinal_max_vlf_active,
((ordinal_min_vlf_active-1)*100.00/vlf_count) AS free_log_pct_before_active_log,
((ordinal_max_vlf_active-(ordinal_min_vlf_active-1))*100.00/vlf_count) AS active_log_pct,
((vlf_count-ordinal_max_vlf_active)*100.00/vlf_count) AS free_log_pct_after_active_log
FROM cte_vlf_cnt;
GO