SQL Server 中完整事务日志的实际原因

Posted

技术标签:

【中文标题】SQL Server 中完整事务日志的实际原因【英文标题】:Actual cause of full transaction log in SQL Server 【发布时间】:2019-03-25 09:07:30 【问题描述】:

我有一个数据库(恢复模式 = 已满),它的事务日志已满。我知道我可以通过缩小事务日志来解决问题。

但是,我想知道它变满的原因是什么?

因为我读过其他人,他们说大量的插入和删除会增加事务日志的大小。但我无法复制该问题以重现完整事务日志的错误(它以某种方式能够重新分配空间)

问题是: 如何模拟“事务日志已满”的问题? 如何查看物理事务日志?

该查询用于跟踪当前占用的日志空间,但它不是实际的事务日志,因为查询的占用空间在批量插入和删除过程中是在颤抖而不是静态增加

假设只要不执行备份,日志空间就会增加

DECLARE @TMPTBL AS TABLE (
DatabaseName nvarchar(500),
LogSize decimal(18,2),
LogSpaceUsed decimal (18,2),
[Status] int
) 

INSERT INTO @TMPTBL
EXEC ('DBCC SQLPERF(LOGSPACE)')

SELECT * FROM @TMPTBL WHERE DATABASENAME LIKE '%MYDBNAME%'
GO

【问题讨论】:

您可以使用这篇文章来查找可能会增加日志文件的长时间运行的查询-***.com/questions/941763/… 你现在可以通过完全备份你的数据库来解决这个问题。注意 - 缩小数据库不是解决此问题的正确方法。 我需要查找长时间运行的查询的原因是什么?它们是导致事务日志已满的原因吗?因为我尝试了相当长的删除和插入(4 个表,每个表都包含产生 1 个插入的触发器),需要 4 分钟才能完成,但之后事务日志很好 我知道修复事务日志完整问题的解决方案(手动),我只是好奇为什么它最终会变满:),如果你能提供脚本让我复制问题(制作事务日志已满) 我只是好奇它是否必须与事务或死锁问题有关 【参考方案1】:

您的问题有多个要点,所以我将尝试逐个回答:

获取日志的大小: 我更喜欢以下内容,因为它包含最大尺寸信息。我并不是说永远不要使用 SQLPERF,我只是在工具箱中添加了另一个工具。还要意识到 SSMS 中有一个磁盘使用情况报告。

SELECT name, size/128 FileSizeInMB
, size/128 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128  AS EmptySpaceInMB
, iif (max_size = -1, null, (max_size)/128) AS MaxSize, iif(max_size > 0, cast(cast((cast(FILEPROPERTY(name, 'SpaceUsed') as decimal) /cast(max_size as decimal)*100) as decimal(18,2)) as varchar), '-') PctFilled
, file_id, type_desc, physical_name
FROM sys.database_files;

检查事务日志中的内容。 您应该探索 fn_dblog。这里有一个简单介绍的链接https://logicalread.com/sql-server-dbcc-log-command-tl01/#.YAnC39hKiUk 这些查询应该可以帮助您入门。这是一个未记录的函数,所以在生产中要小心。

SELECT *
FROM fn_dblog(null, null);

SELECT COUNT(1) as OperationCount,
    SUM (CAST([Log Record Length] as decimal)) as SumRecLen,
    [Operation]
FROM fn_dblog(null, null)
GROUP BY [Operation]    
ORDER BY 2 DESC;

可能的原因: 检查日志的内容将帮助您了解负载的来源。查看具有高 Log Record Length 的操作并继续深入研究。 如果您在列表顶部附近看到操作 LOP_SHRINK_NOOP,您可能需要关闭 Auto Shrink。

如何模拟? 我猜你的意思是触发 9002 错误。我不确定这会完成什么,但这是一种方法。

    关闭日志的自动增长。 将日志的最大大小设置为比当前大小略小一些。如果已分配大量空白空间,您可能需要备份/压缩日志文件。 执行数据操作,直到达到最大大小。考虑移动大量数据的循环或手动事务。示例:创建一个新的物理表,将 1000 个整数插入其中,然后将所有值重复更新 1。

【讨论】:

以上是关于SQL Server 中完整事务日志的实际原因的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server事务日志被填满的原因是啥

sql server日志已满报错

日志链和 SQL Server 事务日志 - 健全性检查

SQL Server 数据库事务日志文件大小急剧增加

sql server运行中,是不是能删除主数据库事务日志文件

SQL Serve 日志体系结构