Le journal des transactions de la base de données est plein

108

J'ai un processus de longue durée qui maintient une transaction ouverte pendant toute la durée.

Je n'ai aucun contrôle sur la manière dont cela est exécuté.

Étant donné qu'une transaction est maintenue ouverte pendant toute la durée, lorsque le journal des transactions se remplit, SQL Server ne peut pas augmenter la taille du fichier journal.

Donc, le processus échoue avec l'erreur "The transaction log for database 'xxx' is full".

J'ai tenté d'éviter cela en augmentant la taille du fichier journal des transactions dans les propriétés de la base de données, mais j'obtiens la même erreur.

Je ne sais pas ce que je devrais essayer ensuite. Le processus dure plusieurs heures, il n'est donc pas facile de jouer à des essais et des erreurs.

Des idées?

Si quelqu'un est intéressé, le processus est une importation d'organisation dans Microsoft Dynamics CRM 4.0.

Il y a beaucoup d'espace disque, nous avons le journal en mode de journalisation simple et avons sauvegardé le journal avant de lancer le processus.

- = - = - = - = - MISE À JOUR - = - = - = - = -

Merci à tous pour les commentaires jusqu'à présent. Voici ce qui m'a amené à croire que le journal ne se développerait pas en raison de la transaction ouverte:

Je reçois l'erreur suivante...

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

Donc, suite à ce conseil, je suis allé à " log_reuse_wait_desc column in sys.databases" et il avait la valeur " ACTIVE_TRANSACTION".

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

Cela signifie ce qui suit:

Une transaction est active (tous les modèles de récupération). • Une transaction de longue durée peut exister au début de la sauvegarde du journal. Dans ce cas, la libération de l'espace peut nécessiter une autre sauvegarde du journal. Pour plus d'informations, consultez «Transactions actives de longue durée», plus loin dans cette rubrique.

• Une transaction est différée (SQL Server 2005 Enterprise Edition et versions ultérieures uniquement). Une transaction différée est en fait une transaction active dont la restauration est bloquée en raison d'une ressource indisponible. Pour plus d'informations sur les causes des transactions différées et comment les sortir de l'état différé, voir Transactions différées.

Ai-je mal compris quelque chose?

- = - = - = - MISE À JOUR 2 - = - = - = -

Je viens de lancer le processus avec une taille de fichier journal initiale de 30 Go. Cela prendra quelques heures.

- = - = - = - MISE À JOUR finale - = - = - = -

Le problème était en fait dû au fait que le fichier journal consommait tout l'espace disque disponible. Dans la dernière tentative, j'ai libéré 120 Go et il a encore utilisé tout cela et a finalement échoué.

Je ne savais pas que cela se produisait auparavant parce que lorsque le processus fonctionnait pendant la nuit, il revenait à l'échec. Cette fois, j'ai pu vérifier la taille du fichier journal avant la restauration.

Merci à tous pour votre contribution.

Jimbo
la source
re "... et ont sauvegardé le journal" .... si la base de données est en mode simple, vous ne pourrez pas sauvegarder le journal, les sauvegardes de journal ne sont pas applicables pour le mode simple. Est-il enregistré en masse?
SqlACID
1
J'ai sauvegardé toute la base de données et l'ai réduite, ce qui a réduit le journal à 1 Mo. J'ai ensuite augmenté la taille du fichier journal à 20 Go au départ, et maintenant 30 Go.
Jimbo

Réponses:

19

S'agit-il d'un script ponctuel ou d'un travail régulier?

Dans le passé, pour les projets spéciaux qui nécessitent temporairement beaucoup d'espace pour le fichier journal, j'ai créé un deuxième fichier journal et je l'ai rendu énorme. Une fois le projet terminé, nous avons supprimé le fichier journal supplémentaire.

Mike Henderson
la source
Je ne dirais pas que c'est un travail ponctuel, mais il est rare que nous devions le faire. Je n'ai pas créé de deuxième fichier journal, mais j'ai augmenté la taille initiale de mon fichier journal actuel à 30 Go. Lors de ma dernière exécution, il était réglé sur 20 Go et il a toujours échoué.
Jimbo
Avoir un deuxième fichier journal serait-il mieux en quelque sorte que d'avoir un gros fichier étant donné que je n'ai qu'un seul lecteur pour travailler?
Jimbo
Si je me souviens maintenant, le fichier supplémentaire nous a principalement permis d'accéder à un autre lecteur plus grand.
Mike Henderson
2
Quelle est la taille des données importées? Si vous importez 30 Go de données, votre fichier journal doit être au moins aussi volumineux.
Mike Henderson
3
La taille du journal est la clé. La tâche en cours a de nouveau échoué et je n'en croyais pas mes yeux quand j'ai vu la taille du fichier journal au point où elle a échoué. Il ne traitait que la moitié des comptes et était déjà à 53 Go. Il semble que je vais devoir nettoyer quelque part dans le voisinage d'un autre 60-70 Go pour pouvoir terminer ce processus.
Jimbo
95

Pour résoudre ce problème, modifiez le modèle de récupération en simple puis réduisez le journal des fichiers

1. Propriétés de la base de données> Options> Modèle de récupération> Simple

2. Tâches de base de données> Réduire> Fichiers> Journal

Terminé.

Vérifiez ensuite la taille de votre fichier journal db dans Propriétés de la base de données> Fichiers> Fichiers de base de données> Chemin

Pour vérifier le journal complet du serveur SQL: ouvrez la visionneuse de fichiers journaux dans SSMS> Base de données> Gestion> Journaux SQL Server> Actuel

user3774600
la source
10
Non, cela ne résout pas le problème. Le problème était que le fichier journal a augmenté pendant un long processus jusqu'à ce qu'il manque d'espace disque. Il a été corrigé en déplaçant temporairement le fichier journal vers un autre lecteur disposant de 1 To d'espace disponible. Vous ne pouvez pas réduire le fichier journal pendant qu'un processus de longue durée - qui maintient une transaction ouverte - est en cours. Ce processus était seul responsable de la croissance du fichier.
Jimbo
Comme @Jimbo l'a déjà dit, cela ne résout pas le problème de l'OP. Cela peut libérer de l'espace actuellement inutilisé, mais dès qu'une longue transaction est à nouveau en cours d'exécution, l'espace sera repris (et échouera probablement encore plus tôt)
Marcel
Parfait! Merci!
Yuri Monteiro
Cela n'a pas résolu le problème. Mon journal ne contient que 500 octets. Je pense que ce problème a commencé après avoir fait une sauvegarde hier.
Ricardo França
C'est certainement le correctif s'il vous reste quelques mégaoctets sur le lecteur complet.
Steve Bauman
36

J'ai eu cette erreur une fois et cela a fini par être le disque dur du serveur qui manquait d'espace disque.

PretoriaCoder
la source
1
Lisez les mises à jour du PO. Cela s'est avéré être le problème.
Colm
18

Avez-vous activé la croissance automatique et la croissance de fichier illimitée pour le fichier journal? Vous pouvez les modifier via SSMS dans "Propriétés de la base de données> Fichiers"

Ross McNab
la source
Oui. Il est réglé sur une croissance automatique de 10%, sans restriction. Le problème est que la croissance automatique ne fonctionnera pas tant qu'il y a une transaction ouverte.
Jimbo
1
Avez-vous une idée de l'ampleur de la transaction? essayez de définir la taille du journal des transactions plus grande que cette estimation, de toute façon si l'allocation de disque n'est pas un problème, allouez au début beaucoup d'espace, pour les données et le journal également. Cela améliore les performances. Ne faites pas la croissance automatique de 10% , faites-le de quelques Go, les performances seront donc assez bonnes.
Luis LL
3
SQL Server fera croître automatiquement le journal pendant une transaction s'il a besoin de plus d'espace pour terminer cette transaction.
Ross McNab
Salut Ross, j'ai fourni ma logique pour penser que la transaction ouverte empêche la croissance d'une mise à jour de la question. Suis-je incorrect dans mon raisonnement?
Jimbo
1
@Jimbo SQL Server ne vous oblige pas à le réserver. Si vous avez la croissance automatique, SQL Server effectue la croissance automatique pendant la transaction. Le fait de l'avoir assez grand peut gagner beaucoup de temps, mais ne devrait pas affecter le processus.
Luis LL
10

C'est une approche à l'ancienne, mais si vous effectuez une mise à jour itérative ou une opération d'insertion dans SQL, quelque chose qui s'exécute pendant une longue période, c'est une bonne idée d'appeler périodiquement (par programme) "checkpoint". L'appel de «point de contrôle» fait en sorte que SQL écrive sur le disque toutes ces modifications de mémoire seule (pages modifiées, elles sont appelées) et les éléments stockés dans le journal des transactions. Cela a pour effet de nettoyer périodiquement votre journal des transactions, évitant ainsi des problèmes comme celui décrit.

Brian
la source
1
Malheureusement, je n'ai aucun contrôle sur la façon dont le processus est exécuté. Dynamics CRM est une application Microsoft et le processus d'importation de l'organisation fait partie de cette application.
Jimbo
1

Ce qui suit tronquera le journal.

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
la source
4
Hey Pinal, cette fonctionnalité a été complètement supprimée de SQL Server 2008 et supérieur: brentozar.com/archive/2009/08/…
Conor
3
Avec les versions ultérieures, essayez BACKUP LOG <myDB> TO DISK = N'NUL: '
HansLindgren
1

Si votre modèle de récupération de base de données est complet et que vous n'avez pas de plan de maintenance de sauvegarde de journal, vous obtiendrez cette erreur car le journal des transactions devient plein en raison de LOG_BACKUP.

Cela empêchera toute action sur cette base de données (par exemple, réduire) et le moteur de base de données SQL Server générera une erreur 9002.

Pour surmonter ce problème, je vous conseille de vérifier ceci Le journal des transactions de la base de données 'SharePoint_Config' est plein en raison de LOG_BACKUP qui montre des étapes détaillées pour résoudre le problème.

Jihan
la source
0

J'ai rencontré l'erreur: «Le journal des transactions de la base de données '...' est plein en raison de 'ACTIVE_TRANSACTION' lors de la suppression des anciennes lignes des tables de ma base de données pour libérer de l'espace disque. J'ai réalisé que cette erreur se produirait si le nombre de lignes à être supprimé était supérieur à 1000000 dans mon cas.Ainsi, au lieu d'utiliser 1 instruction DELETE, j'ai divisé la tâche de suppression en utilisant l'instruction DELETE TOP (1000000) ....

Par exemple:

au lieu d'utiliser cette instruction:

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

en utilisant l'instruction suivante à plusieurs reprises:

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

Mon problème a été résolu avec plusieurs exécutions de suppressions limitées comme

Avant

DELETE FROM TableName WHERE Condition

Après

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

La réponse à la question n'est pas de supprimer les lignes d'une table, mais c'est l'espace tempDB qui est occupé en raison d'une transaction active. cela se produit principalement quand il y a une fusion (upsert) est en cours d'exécution où nous essayons d'insérer la mise à jour et de supprimer les transactions. La seule option est de s'assurer que la base de données est définie sur le modèle de récupération simple et d'augmenter également le fichier à l'espace maximum (ajouter un autre groupe de fichiers). Bien que cela ait ses propres avantages et inconvénients, ce sont les seules options.

L'autre option dont vous disposez est de diviser la fusion (upsert) en deux opérations. l'un qui fait l'insertion et l'autre qui fait la mise à jour et la suppression.

Rohit Reddy
la source
Si vous lisez la question, vous saurez que la base de données était déjà en mode de récupération simple car cela se produisait. Cela n'aide pas lorsque vous avez une transaction ouverte de longue durée. Le fichier continue de croître jusqu'à ce que la transaction soit validée ou annulée. Lisez la première ligne de la question "J'ai un processus de longue durée qui maintient une transaction ouverte pendant toute la durée."
Jimbo
-1

Essaye ça:

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 

J'espère que cela aide.

Saadat
la source
C'était l'une des premières choses tentées et cela est même mentionné dans le texte de la question. Cela ne résout pas le problème d'une seule transaction ouverte remplissant le journal et utilisant tout l'espace disque disponible. Tout ce processus s'est déroulé en mode simple. Cependant, vous êtes l'une des nombreuses personnes qui ont offert cette réponse exacte n'ayant pas lu la question ...
Jimbo
-1

Voici mon code de héros. J'ai fait face à ce problème. Et utilisez ce code pour résoudre ce problème.

 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
la source
Veuillez toujours mettre votre réponse en contexte au lieu de simplement coller du code. Voir ici pour plus de détails.
gehbiszumeis
-1

Essaye ça:

Si possible, redémarrez les services MSSQLSERVER et SQLSERVERAGENT .

Lemraj
la source