数据库的事务日志已满


108

我有一个运行时间很长的过程,可以在整个过程中保持打开事务。

我无法控制它的执行方式。

由于事务在整个持续时间内保持打开状态,因此当事务日志填满时,SQL Server无法增加日志文件的大小。

因此,该过程因错误而失败"The transaction log for database 'xxx' is full"

我试图通过增加数据库属性中事务日志文件的大小来防止这种情况,但是却出现了相同的错误。

不知道下一步该怎么做。该过程运行了几个小时,因此反复试验并不容易。

有任何想法吗?

如果有人感兴趣,该过程就是组织导入 Microsoft Dynamics CRM 4.0.

有足够的磁盘空间,我们在简单的日志记录模式下保存了日志,并且在启动该过程之前已经备份了日志。

-=-=-=-=-更新-=-=-=-=-

到目前为止,感谢所有评论。以下是使我相信由于打开的事务日志不会增长的原因:

我收到以下错误...

Import Organization (Name=xxx, Id=560d04e7-98ed-e211-9759-0050569d6d39) failed with Exception:
System.Data.SqlClient.SqlException: The transaction log for database 'xxx' is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases

因此,按照该建议,我去了“ log_reuse_wait_desc column in sys.databases”,它具有“ ACTIVE_TRANSACTION” 的价值。

根据微软的说法:http : //msdn.microsoft.com/en-us/library/ms345414(v=sql.105).aspx

这意味着:

事务处于活动状态(所有恢复模型)。•日志备份开始时可能存在长时间运行的事务。在这种情况下,释放空间可能需要另一个日志备份。有关更多信息,请参见本主题后面的“长期活动交易”。

•事务被推迟(仅SQL Server 2005 Enterprise Edition和更高版本)。延迟事务实际上是一个活动事务,由于某些资源不可用,其回滚被阻止。有关延迟事务的原因以及如何将其移出延迟状态的信息,请参阅延迟事务。

我有误会吗?

-=-=-=-更新2-=-=-=-

刚开始时,初始日志文件大小设置为30GB。这将需要几个小时才能完成。

-=-=-=-最终更新-=-=-=-

该问题实际上是由日志文件占用了所有可用磁盘空间引起的。在上一次尝试中,我释放了120GB的存储空间,但仍然使用了所有存储空间,最终失败了。

我没有意识到这是以前发生的,因为当流程运行一整夜时,它会因故障而回滚。这次,我能够在回滚之前检查日志文件的大小。

谢谢大家的投入。


重新“ ...并已备份日志”...。如果数据库处于简单模式,则将无法备份日志,日志备份不适用于简单模式。是否批量记录?
SqlACID

1
我备份了整个数据库并将其缩小,导致Log缩小到1MB。然后,我最初将日志文件的大小增加到20GB,现在增加到30GB。
Jimbo

Answers:


19

这是一次性脚本还是定期发生的工作?

过去,对于临时需要大量日志文件空间的特殊项目,我创建了第二个日志文件并将其扩大。项目完成后,我们将删除多余的日志文件。


我不会说这是一项一次性的工作,但是我们很少要做。我没有创建第二个日志文件,但确实将当前日志文件的初始大小增加到30GB。在我上次运行时,它设置为20GB,但仍然失败。
Jimbo

考虑到我只有一个驱动器,第二个日志文件会比一个大文件好吗?
Jimbo

我现在记得,附加文件主要使我们能够访问另一个更大的驱动器。
Mike Henderson

2
导入的数据有多大?如果您要导入30 GB的数据,则您的日志文件可能至少需要一样大。
Mike Henderson

3
日志大小是关键。当前任务再次失败,当我在失败时看到日志文件的大小时,我不敢相信。它只处理了一半的帐户,已经有53GB的空间。看来我必须清除另一个60-70GB附近的空间才能完成此过程。
Jimbo

95

若要解决此问题,请将恢复模型更改为简单,然后将文件收缩

1. 数据库属性>选项>恢复模型>简单

2. 数据库任务>收缩>文件>日志

做完了

然后在“ 数据库属性”>“文件”>“数据库文件”>“路径”中检查数据库日志文件的大小。

要检查完整的sql服务器日志:在SSMS>数据库>管理> SQL Server日志>当前打开日志文件查看器。


10
不,那不能解决问题。问题是日志文件在长时间运行过程中增长,直到磁盘空间用完为止。通过将日志文件临时移动到另一个具有1TB可用空间的驱动器来进行更正。在长时间运行的过程中(正在打开一个事务),您无法收缩日志文件。该过程完全负责文件的增长。
Jimbo 2014年

正如@Jimbo已经说过的那样,这不能解决OP的问题。它可能会释放一些当前未使用的空间,但是一旦长事务再次运行,该空间将被再次占用(并且可能甚至会更早失败)
Marcel

完善!谢谢!
Yuri Monteiro

那没有解决问题。我的日志只有500个字节。我认为这个问题是在昨天完成备份后开始的。
里卡多·弗朗萨

如果您还有几兆字节可用于整个驱动器,则绝对可以解决此问题。
史蒂夫·鲍曼


18

是否同时为日志文件启用了启用自动增长不受限制的文件增长?您可以通过SSMS在“数据库属性>文件”中进行编辑


是。设置为自动增长10%,不受限制。问题是在有未结交易时自动增长将不起作用。
Jimbo

1
您知道交易有多大吗?尝试将“事务日志”的大小设置为大于该估计值,如果磁盘分配不是问题,则应在开始时为数据和日志分配足够的空间。它提高了性能。我们不要以10%的速度自动增长,而是以几GB的速度增长,因此性能将足够好。
Luis LL,

3
SQL Server的一个事务期间自动增长,日志,如果它需要更多的空间来完成该项交易。
罗斯麦克纳布

罗斯,您好,我提供了我的逻辑,认为公开交易会阻止问题更新的增长。我的推理不正确吗?
Jimbo

1
@Jimbo SQL Server不需要您保留它。如果具有自动增长功能,SQL Server将在事务期间进行自动增长。具有足够大的尺寸可以节省大量时间,但不应影响该过程。
Luis LL

10

这是一种古老的方法,但是如果您要在SQL中执行迭代更新或插入操作(这种方法会运行很长时间),则最好定期(以编程方式)调用“检查点”。调用“检查点”会使SQL将所有这些仅内存更改(称为脏页)和存储在事务日志中的项目写入磁盘。这具有定期清除事务日志的效果,从而避免了上述问题。


1
不幸的是,我无法控制执行过程的方式。Dynamics CRM是Microsoft应用程序,组织导入过程是该应用程序的一部分。
Jimbo

1

下面将截断日志。

USE [yourdbname] 
GO

-- TRUNCATE TRANSACTION LOG --
DBCC SHRINKFILE(yourdbname_log, 1)
BACKUP LOG yourdbname WITH TRUNCATE_ONLY
DBCC SHRINKFILE(yourdbname_log, 1)
GO

-- CHECK DATABASE HEALTH --
ALTER FUNCTION [dbo].[checker]() RETURNS int AS BEGIN  RETURN 0 END
GO

4
嘿Pinal,此功能已从SQL Server 2008及更高版本中完全删除:brentozar.com/archive/2009/08/…–
Conor

3
对于更高版本,请尝试将BACKUP LOG <myDB> TO DISK = N'NUL:'
HansLindgren

1

如果您的数据库恢复模型已满,并且没有日志备份维护计划,则会出现此错误,因为事务日志由于变为已满LOG_BACKUP

这将防止对该数据库执行任何操作(例如,收缩),并且SQL Server数据库引擎将引发9002错误。

要解决此问题,我建议您检查此问题。由于LOG_BACKUP显示了解决问题的详细步骤,因此数据库'SharePoint_Config'的事务日志已满


0

我遇到错误:“由于'ACTIVE_TRANSACTION',数据库'...'的事务日志已满,同时从数据库表中删除旧行以释放磁盘空间。我意识到,如果要删除的行数会出现此错误。在我的情况下,被删除的内容大于1000000,因此我不使用1 DELETE语句,而是使用DELETE TOP(1000000)....语句对删除任务进行了划分。

例如:

而不是使用以下语句:

DELETE FROM Vt30 WHERE Rt < DATEADD(YEAR, -1, GETDATE())

反复使用以下语句:

DELETE TOP(1000000) FROM Vt30 WHERE Rt < DATEADD(YEAR, -1, GETDATE())


-1

这个问题的答案不是从表中删除行,而是由于活动事务而占用的tempDB空间。这种情况通常发生在运行合并(upsert)时,我们尝试插入更新和删除事务。唯一的选择是确保将数据库设置为简单恢复模式,并且还将文件增加到最大空间(添加另一个文件组)。尽管这有其自身的优缺点,但这是唯一的选择。

您拥有的另一个选项是将merge(upsert)分为两个操作。一个执行插入操作,另一个执行更新和删除操作。


如果您读了这个问题,您会知道数据库已经处于简单的恢复模式,因为这种情况正在发生。当您有一个长时间运行的未清事务时,这无济于事。文件将继续增长,直到事务被提交或回滚。阅读问题的第一行“我有一个长期运行的流程,可以在整个期间内保持一个事务的打开状态”。
Jimbo

-1

试试这个:

USE YourDB;  
GO  
-- Truncate the log by changing the database recovery model to SIMPLE.  
ALTER DATABASE YourDB
SET RECOVERY SIMPLE;  
GO  
-- Shrink the truncated log file to 50 MB.  
DBCC SHRINKFILE (YourDB_log, 50);  
GO  
-- Reset the database recovery model.  
ALTER DATABASE YourDB
SET RECOVERY FULL;  
GO 

希望对您有所帮助。


这是最初尝试的事情之一,甚至在问题文本中也提到过。这不能解决单个打开的事务填充日志并使用所有可用磁盘空间的问题。整个过程以简单模式进行。但是,你是谁提供了这个确切的答案具有不阅读问题很多人的一个...
金宝

-1

这是我的英雄代码。我已经遇到了这个问题。并使用此代码解决此问题。

 USE master;

    SELECT 
        name, log_reuse_wait, log_reuse_wait_desc, is_cdc_enabled 
    FROM 
        sys.databases 
    WHERE 
        name = 'XX_System';

    SELECT DATABASEPROPERTYEX('XX_System', 'IsPublished');


    USE XX_System;
    EXEC sp_repldone null, null, 0,0,1;
    EXEC sp_removedbreplication XX_System;


    DBCC OPENTRAN;
    DBCC SQLPERF(LOGSPACE);
    EXEC sp_replcounters;



    DBCC SQLPERF(LOGSPACE);

请始终将答案放在上下文中,而不仅仅是粘贴代码。有关更多详细信息,请参见此处
gehbiszumeis

-1

试试这个:

如果可能,请重新启动服务MSSQLSERVERSQLSERVERAGENT

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.