El registro de transacciones de la base de datos está lleno

108

Tengo un proceso de ejecución prolongada que mantiene abierta una transacción durante toda su duración.

No tengo control sobre la forma en que esto se ejecuta.

Debido a que una transacción se mantiene abierta durante toda la duración, cuando se llena el registro de transacciones, SQL Server no puede aumentar el tamaño del archivo de registro.

Entonces el proceso falla con el error "The transaction log for database 'xxx' is full".

Intenté evitar esto aumentando el tamaño del archivo de registro de transacciones en las propiedades de la base de datos, pero obtengo el mismo error.

No estoy seguro de qué debería intentar a continuación. El proceso se ejecuta durante varias horas, por lo que no es fácil jugar a prueba y error.

¿Algunas ideas?

Si alguien está interesado, el proceso es una importación de la organización en Microsoft Dynamics CRM 4.0.

Hay mucho espacio en disco, tenemos el registro en modo de registro simple y hemos hecho una copia de seguridad del registro antes de iniciar el proceso.

- = - = - = - = - ACTUALIZAR - = - = - = - = -

Gracias a todos por los comentarios hasta ahora. Lo siguiente es lo que me llevó a creer que el registro no crecería debido a la transacción abierta:

Estoy teniendo el siguiente error...

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

Así que siguiendo ese consejo fui a " log_reuse_wait_desc column in sys.databases" y tenía el valor " ACTIVE_TRANSACTION".

Según Microsoft: http://msdn.microsoft.com/en-us/library/ms345414(v=sql.105).aspx

Eso significa lo siguiente:

Una transacción está activa (todos los modelos de recuperación). • Puede existir una transacción de larga duración al inicio de la copia de seguridad del registro. En este caso, liberar espacio puede requerir otra copia de seguridad del registro. Para obtener más información, consulte "Transacciones activas de larga duración", más adelante en este tema.

• Se aplaza una transacción (SQL Server 2005 Enterprise Edition y versiones posteriores únicamente). Una transacción diferida es efectivamente una transacción activa cuya reversión está bloqueada debido a algún recurso no disponible. Para obtener información sobre las causas de las transacciones diferidas y cómo sacarlas del estado diferido, consulte Transacciones diferidas.

¿He entendido mal algo?

- = - = - = - ACTUALIZAR 2 - = - = - = -

Acabo de iniciar el proceso con el tamaño del archivo de registro inicial establecido en 30 GB. Esto tardará un par de horas en completarse.

- = - = - = - ACTUALIZACIÓN final - = - = - = -

En realidad, el problema se debió a que el archivo de registro consumía todo el espacio disponible en disco. En el último intento liberé 120 GB y todavía lo usó todo y finalmente falló.

No me di cuenta de que esto estaba sucediendo anteriormente porque cuando el proceso se estaba ejecutando durante la noche, estaba retrocediendo por falla. Esta vez pude comprobar el tamaño del archivo de registro antes de la reversión.

Gracias a todos por sus aportes.

Jimbo
fuente
re "... y ha realizado una copia de seguridad del registro" .... si la base de datos está en modo simple, no podrá realizar una copia de seguridad del registro, las copias de seguridad del registro no son aplicables para el modo simple. ¿Es un registro masivo?
SqlACID
1
Hice una copia de seguridad de toda la base de datos y la reduje, lo que provocó que el registro se redujera a 1 MB. Luego, aumenté el tamaño del archivo de registro a 20 GB inicialmente, y ahora a 30 GB.
Jimbo

Respuestas:

19

¿Es este un guión de una sola vez o un trabajo habitual?

En el pasado, para proyectos especiales que requieren temporalmente mucho espacio para el archivo de registro, creé un segundo archivo de registro y lo hice enorme. Una vez que el proyecto está completo, eliminamos el archivo de registro adicional.

Mike Henderson
fuente
No diría que es un trabajo de una sola vez, pero es raro que tengamos que hacerlo. No creé un segundo archivo de registro, pero aumenté el tamaño inicial de mi archivo de registro actual a 30 GB. Durante mi última ejecución, se configuró en 20 GB y aún falló.
Jimbo
¿Sería mejor tener un segundo archivo de registro de alguna manera que tener uno grande dado que solo tengo una unidad para trabajar?
Jimbo
Como recuerdo ahora, el archivo adicional en su mayoría nos permitió acceder a otra unidad más grande.
Mike Henderson
2
¿Qué tamaño tienen los datos que se importan? Si está importando 30 GB de datos, es posible que su archivo de registro deba ser al menos tan grande.
Mike Henderson
3
El tamaño del registro es la clave. La tarea actual falló de nuevo y no podía creer lo que veía cuando vi el tamaño del archivo de registro en el punto en el que falló. Solo procesó la mitad de las cuentas y ya tenía 53 GB. Parece que tendré que despejar en algún lugar cercano a otros 60-70 GB para poder completar este proceso.
Jimbo
95

Para solucionar este problema, cambie el Modelo de recuperación a Simple y luego reduzca el registro de archivos

1. Propiedades de la base de datos> Opciones> Modelo de recuperación> Simple

2. Tareas de base de datos> Reducir> Archivos> Registro

Hecho.

Luego verifique el tamaño de su archivo de registro db en Propiedades de la base de datos> Archivos> Archivos de base de datos> Ruta

Para verificar el registro completo del servidor SQL: abra el Visor de archivos de registro en SSMS> Base de datos> Administración> Registros de SQL Server> Actual

usuario3774600
fuente
10
No, eso no soluciona el problema. El problema fue que el archivo de registro creció durante un proceso de larga ejecución hasta que se quedó sin espacio en el disco. Se corrigió moviendo temporalmente el archivo de registro a otra unidad que tenía 1 TB de espacio disponible. No puede reducir el archivo de registro mientras un proceso de larga ejecución, que mantiene abierta una transacción, está en curso. Ese proceso fue el único responsable del crecimiento del archivo.
Jimbo
Como ya dijo @Jimbo, esto no soluciona el problema del OP. Puede liberar algo de espacio no utilizado actualmente, pero tan pronto como se vuelva a ejecutar una transacción larga, el espacio se volverá a ocupar (y probablemente fallará incluso antes)
Marcel
¡Perfecto! ¡Gracias!
Yuri Monteiro
Eso no solucionó el problema. Mi registro tiene solo 500 bytes. Creo que este problema comenzó después de que hice una copia de seguridad ayer.
Ricardo França
Esta es definitivamente la solución si le quedan un par de megabytes de sobra en el disco completo.
Steve Bauman
36

Tuve este error una vez y terminó siendo el disco duro del servidor el que se quedó sin espacio en disco.

PretoriaCoder
fuente
1
Lea las actualizaciones del OP. Este resultó ser el problema.
Colm
18

¿Tiene Habilitar Crecimiento automático y Crecimiento de archivo sin restricciones habilitados para el archivo de registro? Puede editarlos a través de SSMS en "Propiedades de la base de datos> Archivos"

Ross McNab
fuente
Si. Está configurado para crecer automáticamente un 10%, sin restricciones. El problema es que el crecimiento automático no funcionará mientras haya una transacción abierta.
Jimbo
1
¿Tiene idea de lo grande que será la transacción? intente establecer el tamaño del registro de transacciones más grande que esa estimación; de todos modos, si la asignación del disco no es un problema, asigne al principio suficiente espacio para los datos y el registro también. Mejora el rendimiento. No crezcamos automáticamente en un 10% , hágalo en unos pocos GB, para que el rendimiento sea lo suficientemente bueno.
Luis LL
3
SQL Server va a crecer automáticamente el registro durante una transacción si se necesita más espacio para completar la transacción.
Ross McNab
Hola Ross, proporcioné mi lógica para pensar que la transacción abierta está impidiendo el crecimiento en una actualización de la pregunta. ¿Soy incorrecto en mi razonamiento?
Jimbo
1
@Jimbo SQL Server no requiere que lo tengas reservado. Si tiene crecimiento automático, SQL Server lo hace durante la transacción. Tenerlo lo suficientemente grande puede ahorrar mucho tiempo, pero no debería afectar el proceso.
Luis LL
10

Este es un enfoque de la vieja escuela, pero si está realizando una actualización iterativa o una operación de inserción en SQL, algo que se ejecuta durante mucho tiempo, es una buena idea llamar periódicamente (mediante programación) al "punto de control". Llamar a "punto de control" hace que SQL escriba en el disco todos esos cambios de sólo memoria (páginas sucias, se llaman) y elementos almacenados en el registro de transacciones. Esto tiene el efecto de limpiar su registro de transacciones periódicamente, evitando así problemas como el descrito.

Brian
fuente
1
Desafortunadamente, no tengo control sobre la forma en que se realiza el proceso. Dynamics CRM es una aplicación de Microsoft y el proceso de importación de la organización es parte de esa aplicación.
Jimbo
1

Lo siguiente truncará el registro.

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
Pinal
fuente
4
Hola Pinal, esta funcionalidad se eliminó por completo de SQL Server 2008 y superior: brentozar.com/archive/2009/08/…
Conor
3
Con versiones posteriores, intente BACKUP LOG <myDB> TO DISK = N'NUL: '
HansLindgren
1

Si su modelo de recuperación de la base de datos está completo y no tenía un plan de mantenimiento de copia de seguridad del registro, recibirá este error porque el registro de transacciones se llena debido a LOG_BACKUP.

Esto evitará cualquier acción en esta base de datos (por ejemplo, reducción) y el motor de base de datos de SQL Server generará un error 9002.

Para superar este comportamiento, le aconsejo que compruebe esto. El registro de transacciones de la base de datos 'SharePoint_Config' está lleno debido a LOG_BACKUP que muestra los pasos detallados para resolver el problema.

Jihan
fuente
0

Me encontré con el error: "El registro de transacciones para la base de datos '...' está lleno debido a 'ACTIVE_TRANSACTION' mientras borraba filas antiguas de las tablas de mi base de datos para liberar espacio en disco. Me di cuenta de que este error ocurriría si el número de filas para En mi caso, ser eliminado era mayor que 1000000. Entonces, en lugar de usar 1 declaración DELETE, dividí la tarea de eliminación usando DELETE TOP (1000000) .... declaración.

Por ejemplo:

en lugar de usar esta declaración:

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

usando la siguiente declaración repetidamente:

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

Mi problema se resolvió con ejecución múltiple de eliminaciones limitadas como

antes de

DELETE FROM TableName WHERE Condition

Después

DELETE TOP(1000) FROM TableName WHERECondition
Amir Astaneh
fuente
-1

La respuesta a la pregunta no es eliminar las filas de una tabla, sino el espacio tempDB que se está ocupando debido a una transacción activa. esto sucede principalmente cuando se está ejecutando una fusión (upsert) en la que intentamos insertar actualizaciones y eliminar las transacciones. La única opción es asegurarse de que la base de datos esté configurada en un modelo de recuperación simple y también aumentar el archivo al espacio máximo (agregar otro grupo de archivos). Aunque esto tiene sus propias ventajas y desventajas, estas son las únicas opciones.

La otra opción que tiene es dividir la combinación (upsert) en dos operaciones. uno que inserta y el otro que actualiza y elimina.

Rohit Reddy
fuente
Si lee la pregunta, sabrá que la base de datos ya estaba en modo de recuperación simple mientras esto sucedía. Esto no ayuda cuando tiene una transacción abierta de larga duración. El archivo continúa creciendo hasta que la transacción se confirma o se deshace. Lea la primera línea de la pregunta "Tengo un proceso de larga ejecución que mantiene abierta una transacción durante toda su duración".
Jimbo
-1

Prueba esto:

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 

Espero que ayude.

Saadat
fuente
Esta fue una de las primeras cosas que se intentó e incluso se menciona en el texto de la pregunta. Esto no resuelve el problema de una sola transacción abierta que llena el registro y utiliza todo el espacio disponible en disco. Todo este proceso se llevó a cabo en modo simple. Sin embargo, eres una de las muchas personas que ofrecieron esta respuesta exacta sin haber leído la pregunta ...
Jimbo
-1

Aquí está mi código de héroe. Me he enfrentado a este problema. Y usa este código para arreglar esto.

 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);
narawit1601
fuente
Por favor, ponga su respuesta siempre en contexto en lugar de simplemente pegar el código. Consulte aquí para obtener más detalles.
gehbiszumeis
-1

Prueba esto:

Si es posible, reinicie los servicios MSSQLSERVER y SQLSERVERAGENT .

Lemraj
fuente