为什么在具有简单恢复模型和自动增长日志文件的数据库上,由于“ACTIVE_TRANSACTION”,我会得到数据库“X”的事务日志已满?
失败的操作正在执行很多很多 Insert 语句。插入语句不在事务内发生。我不明白为什么事务日志必须如此大,我不明白为什么它无法增长。
当我看到这个错误时,通常是因为有一个长时间运行的事务尚未提交。请注意,长时间运行的事务的大小不一定是问题所在。如果事务更改了任何数量的数据,它将阻止事务日志清除该 VLF。因此,如果您的事务日志是 1 GB,并且您在数据库中进行的活动需要超过 1 GB 的事务日志,因为您最旧的活动事务可能会遇到问题。
对于一个简单的演示,我有一个恢复模型为SIMPLE
和日志限制为 100 MB 的数据库。在一个会话中,我在循环中插入和删除数据:
create table dbo.X_DUMMY_TABLE (COL VARCHAR(4000));
SET NOCOUNT ON;
-- truncate and insert data in a loop
WHILE 1 = 1
BEGIN
TRUNCATE TABLE X_DUMMY_TABLE
BEGIN TRANSACTION
INSERT INTO dbo.X_DUMMY_TABLE
SELECT REPLICATE('Z', 4000)
FROM dbo.getNums(100);
COMMIT TRANSACTION;
CHECKPOINT;
END;
Run Code Online (Sandbox Code Playgroud)
使用这种恢复模型SIMPLE
不会导致任何问题。使用DBCC SQLPERF(LOGSPACE)
我可以看到日志已满 1 - 7%。请注意,事务日志文件本身保持在 100 MB。
现在我将在另一个会话中启动一个仅插入一行的事务。我不会提交交易:
create table dbo.X_DUMMY_TABLE_2 (COL VARCHAR(4000))
BEGIN TRANSACTION
INSERT INTO dbo.X_DUMMY_TABLE_2
SELECT 'Z';
-- note the lack of a COMMIT
Run Code Online (Sandbox Code Playgroud)
大约 3 秒后,第一个会话抛出此错误:
Msg 9002, Level 17, State 4, Line 11
由于“ACTIVE_TRANSACTION”,数据库“SE_DB3”的事务日志已满。