由于活动事务,SQL Server 日志已满

Posted

技术标签:

【中文标题】由于活动事务,SQL Server 日志已满【英文标题】:SQL Server Log full due to active transaction 【发布时间】:2019-04-08 10:42:26 【问题描述】:

我一直在尝试更新表中的列,但出现以下错误:

 The transaction log for database 'STAGING' is full due to 'ACTIVE_TRANSACTION'.

我正在尝试运行以下语句:

UPDATE [STAGING].[dbo].[Stg_Encounter_Alias]
    SET
        [valid_flag]            = 1

    FROM  [Stg_Encounter_Alias] Stg_ea
    where [ACTIVE_IND] = 1
        and [END_EFFECTIVE_DT_TM] > convert(date,GETDATE())

我的表有大约 1800 万行。并且上面的更新会修改所有的行。表大小为 2.5 GB。数据库也处于简单恢复模式

这是我会在不同的桌子上经常做的事情。我该如何管理?

我的数据库大小如下

以下是数据库属性!!!我已尝试将日志大小更改为无限制,但它会恢复为默认值。

谁能告诉我处理这种情况的有效方法?

如果我分批运行:

begin
DECLARE @COUNT INT
SET @COUNT = 0

SET NOCOUNT ON;      
DECLARE @Rows INT,
    @BatchSize INT; -- keep below 5000 to be safe

SET @BatchSize = 2000;

SET @Rows = @BatchSize; -- initialize just to enter the loop


WHILE (@Rows = @BatchSize)
BEGIN
  UPDATE TOP (@BatchSize) [STAGING].[dbo].[Stg_Encounter_Alias]
    SET
        [valid_flag]            = 1

    FROM  [Stg_Encounter_Alias] Stg_ea
    where [ACTIVE_IND] = 1
        and [END_EFFECTIVE_DT_TM] > convert(date,GETDATE())
  SET @Rows = @@ROWCOUNT;
END;
end

【问题讨论】:

谢谢米奇!!您能否建议任何内存更改以及我可以做的让它处理更多更新/插入 不,END_EFFECTIVE_DT_TM 上没有索引。我会尝试分批运行它。实际上,我一直在同一张表上进行批量截断,并且它们在相同的行数上运行得很好。但不知何故更新失败!我在另一个具有相同配置的数据库上进行了相同的更新,并且成功了。 【参考方案1】:

您在单个事务中执行更新,这会导致事务日志变得非常大。

改为分批执行更新,例如一次 50K - 100K。

您在END_EFFECTIVE_DT_TM 上是否有包含ACTIVE_INDvalid_flag 的索引?这将有助于提高性能。

CREATE INDEX NC_Stg_Encounter_Alias_END_EFFECTIVE_DT_TM_I_ 
ON [dbo].[Stg_Encounter_Alias](END_EFFECTIVE_DT_TM) 
INCLUDE (valid_flag) 
WHERE ([ACTIVE_IND] = 1);

如果您运行的是 Enterprise Edition 或 SQL Server 2016 SP1 或更高版本(任何版本),另一件可以显着提高性能的方法是为表及其索引打开 data_compression = page

【讨论】:

我已经更新了上面问题中的代码,如果我批量运行它会运行得非常慢!!!当我在另一个数据库中运行相同的查询时,它在另一个数据库中的速度非常快!!! 你的批处理大小是 2K,比我建议的要小得多。分批运行应该只会稍微慢一点......你创建了索引吗?另一个数据库可能位于具有不同硬件规格的服务器上?您通过添加 TOP 更改了查询...您有主键吗? 这实际上是一个没有索引的临时数据库。我在 end_effective_dt_tm 上添加了一个索引,但对速度没有帮助!!!另一个 DB 与这个 DB 具有完全相同的配置。不知道怎么回事!!我也尝试过 100k,查询已经运行了 15 分钟。没有尽快完成的迹象!!! 您是否预先调整了 TLog 的大小? TLog 文件是否在快速存储上?表有主键吗?它是堆还是有聚集索引? 我有你建议的索引,我使用的批量大小是 100000。查询运行了 15 个小时,我手动停止了它。我一直在使用所有默认设置。我不知道如何检查快速存储或预先调整 Tlog 的大小。【参考方案2】:

感谢您的帮助米奇。我实际上已经增加了事务日志的大小并删除了所有索引作为它的暂存数据库。它在 24 秒内更新了 1700 万行 :)

虽然我对解决方案不是很满意,但由于时间不够,我会更进一步。我将不得不进一步提高效率。

【讨论】:

以上是关于由于活动事务,SQL Server 日志已满的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft SQL Server - 事务日志已满是啥意思?

关于SQL Server事务日志的问题汇总

SQL SERVER 日志已满的处理方法 (转)

SQL SERVER 日志已满的处理方法 (转)

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

sql server 2012 事务日志在哪