122

我有一个长时间运行的进程,可以在整个持续时间内保持打开事务。

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

因为事务在整个持续时间内保持打开状态,所以当事务日志填满时,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,但它仍然使用了所有空间,最终失败了。

我之前没有意识到这会发生,因为当进程在一夜之间运行时,它会在失败时回滚。这次我能够在回滚之前检查日志文件的大小。

感谢大家的意见。

4

14 回答 14

107

要解决此问题,请将恢复模式更改为简单,然后缩小文件日志

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

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

完毕。

然后在Database Properties > Files > Database Files > Path检查您的数据库日志文件大小

要检查完整的 sql server 日志:在 SSMS > Database > Management > SQL Server Logs > Current 打开 Log File Viewer

于 2014-07-14T03:16:34.410 回答
44

我曾经遇到过这个错误,它最终是服务器的硬盘驱动器磁盘空间不足。

于 2014-06-05T13:59:18.177 回答
21

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

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

于 2013-07-16T11:35:01.683 回答
18

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

于 2013-07-16T11:21:54.337 回答
11

这是一种老派的方法,但如果您在 SQL 中执行迭代更新或插入操作,这种操作会运行很长时间,定期(以编程方式)调用“检查点”是个好主意。调用“检查点”会导致 SQL 将所有那些仅用于内存的更改(称为脏页)和存储在事务日志中的项目写入磁盘。这具有定期清理事务日志的效果,从而防止出现上述问题。

于 2013-07-16T12:17:33.910 回答
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
于 2014-04-05T14:43:26.427 回答
1

如果您的数据库恢复模式已满且您没有日志备份维护计划,您将收到此错误,因为事务日志因LOG_BACKUP.

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

为了克服这种行为,我建议您检查此数据库“SharePoint_Config”的事务日志已满,因为 LOG_BACKUP显示了解决问题的详细步骤。

于 2016-07-06T00:04:05.507 回答
1

我遇到了错误:“数据库 '...' 的事务日志已满,由于 '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())
于 2018-08-14T04:14:34.123 回答
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 

我希望它有所帮助。

于 2019-06-10T15:33:45.463 回答
1

加上上面的答案,我还想提一下,如果可能的话,你也可以释放服务器来解决这个问题。如果由于数据库溢出而导致服务器已满,您可以从构建您的数据库的服务器中删除一些不必要的文件。至少这暂时解决了问题并让您查询数据库

于 2021-07-14T05:59:38.717 回答
0

我的问题通过多次执行有限删除解决了,比如

DELETE FROM TableName WHERE Condition

DELETE TOP(1000) FROM TableName WHERECondition
于 2019-06-30T05:45:30.420 回答
-1

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

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

于 2018-10-07T19:00:16.633 回答
-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);
于 2019-11-13T06:36:24.417 回答
-2

尝试这个:

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

于 2020-02-26T17:46:22.010 回答