web-dev-qa-db-fra.com

Comment réduire les opérations de journal dans SQL Server pour éviter l'erreur «journal plein»

J'ai une base de données en production qui est constamment remplie de fichiers journaux, c'est un entrepôt de données et j'ai de nombreux emplois/requêtes en cours pour des raisons évidentes. Voici l'erreur que j'obtiens

Msg 9002, Level 17, State 4, Line 7
The transaction log for database  is full due to 'ACTIVE_TRANSACTION'. 

Maintenant, cela a du sens et je comprends que SQL ne peut pas effectuer d'action car son fichier journal est rempli. J'ai deux fichiers journaux

  • Disque D avec une croissance illimitée et une croissance automatique activée [taille du disque D 180 Go]
  • Lecteur E de taille statique [lecteur E 120 Go, taille du fichier journal: 20 Go]

J'ai fait quelques recherches sur ce problème et trouvé une solution possible: Source

  • Sauvegarde du journal.
  • Libérer de l'espace disque pour que le journal puisse augmenter automatiquement.
  • Déplacement du fichier journal vers un lecteur de disque avec suffisamment d'espace.
  • Augmenter la taille d'un fichier journal.
  • Ajout d'un fichier journal sur un autre disque.
  • Terminer ou tuer une transaction de longue durée.

Maintenant, en supposant que j'ai un espace limité (c'est-à-dire 180 Go + 20 Go), ce qui, je pense, est assez bon pour une base de données en MODE DE RÉCUPÉRATION SIMPLE. Comment puis-je identifier ce problème et faire une correction avant qu'il ne survienne?

Réplication :

J'ai essayé de reproduire ce scénario en créant un nouvel exemple de base de données avec le paramètre ci-dessous enter image description here

et sous la requête pour obtenir des millions de lignes et les insérer dans le tableau

SET NOCOUNT ON;
DECLARE @SET_SIZE INT = 500000000;

CREATE TABLE dbo.Test500Million (N INT  PRIMARY KEY CLUSTERED NOT NULL);

;WITH T(N) AS (SELECT N FROM (VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) AS X(N))
,NUMS(N) AS (SELECT TOP(@SET_SIZE) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS N FROM T T1, T T2, T T3, T T4, T T5, T T6, T T7, T T8, T T9)
INSERT INTO dbo.Test500Million(N)
SELECT N FROM NUMS;

DROP TABLE dbo.Test500Million 

Maintenant, lors de la validation de sys.databases et de la recherche d'un message d'erreur, je trouve les deux CHECKPOINTS & ACTIVE_TRANSACTION.

Mes questions :

  • Sur mon observation, j'ai constaté que cela ne se produit qu'avec l'instruction insert et non avec select. Donc, je suppose que les entrées de journal ne seront destinées qu'à l'instruction INSERT/UPDATE et non à l'instruction SELECT dans tous les cas. Ai-je raison?
  • Comment réduire la journalisation lors de l'insertion des enregistrements de mise à jour? J'ai déjà un MODE DE RÉCUPÉRATION SIMPLE.
  • J'ai trouvé que le débit moyen au cours de cette période est passé de 25 Mo environ. à 1,2 Mo. Qu'est-ce que ça veut dire?
  • Existe-t-il un autre moyen de résoudre ce problème, autre que l'augmentation de l'espace disque?
  • Si la seule option est de réduire un fichier, alors quand dois-je le faire? Puis-je le faire lorsqu'une transaction active est activée? [Environnement de production]

Veuillez me faire savoir si vous avez besoin de plus de statistiques que je peux collecter.

6
Zerotoinfinity

• D'après mon observation, j'ai constaté que cela ne se produit qu'avec l'instruction insert et non avec select. Donc, je suppose que les entrées de journal ne seront destinées qu'à l'instruction INSERT/UPDATE et non à l'instruction SELECT dans tous les cas. Ai-je raison?

L'instruction Select en tant que telle n'est pas consignée par rapport aux instructions DML telles que l'insertion, la mise à jour et la suppression. Si vous voyez la sortie de fn_dblog pour l'instruction select, il n'aura aucune entrée. Mais il y aurait de nombreuses entrées pour les instructions DML. Veuillez noter . Le journal des transactions est conservé et les informations relatives aux transactions y sont écrites de sorte que pendant la récupération après incident ou la récupération, SQL Server puisse savoir quelles transactions ont été validées et ce qui n'a pas été validé et en le lisant, il peut mettre la base de données dans un état cohérent CECI IS POURQUOI le journal est si nécessaire. Sans le journal des transactions, la récupération n'est pas possible

À toutes fins pratiques, chaque transaction est enregistrée dans SQL Server. Vous NE POUVEZ PAS avoir de scénario dans lequel vous exécutez une transaction et rien n'est enregistré dans le journal des transactions. Vous n'avez aucune option pour désactiver la journalisation dans SQL Server. Je vous suggère de lire Journalisation et récupération dans SQL Server .

• Comment puis-je réduire la journalisation lors de l'insertion des enregistrements de mise à jour? J'ai déjà un MODE DE RÉCUPÉRATION SIMPLE

Vous vous trompez que la journalisation ne se produit pas dans un modèle de récupération simple, mais que lorsque la transaction est validée, le journal des transactions est tronqué et l'espace utilisé par les journaux générés pour la transaction est réutilisé. En fait, la journalisation de la récupération simple est presque identique à la récupération complète et la différence se situe lorsque la troncature du journal se produit. Oui, vous pouvez avoir une journalisation minimale dans le modèle de récupération en bloc pour seulement certaines commandes . Pour les commandes de repos, même dans un modèle de récupération enregistré en bloc, la journalisation serait complète.

• J'ai constaté que le débit moyen au cours de cette période est passé de 25 Mo environ. à 1,2 Mo. Qu'est-ce que ça veut dire?

Je ne peux pas comprendre cela. Pouvez-vous l'expliquer.

• Existe-t-il un autre moyen de résoudre ce problème, autre que l'augmentation de l'espace disque?

Comme déjà suggéré, vous êtes le plus susceptible de faire face à un problème si vous gardez @SET_SIZE INT = 500000000 (même si c'est factice) pourquoi une telle limite élevée. Pouvez-vous le réduire à 500 000 et voir comment se comporte le fichier journal. Assurez-vous qu'auotgrowth du fichier journal est en Mo et défini sur une valeur raisonnable. Effectuez la transaction par lots. Enfin, si vous lisez Pourquoi le journal des transactions continue de croître ou manque d'espace vous pouvez avoir une bonne idée.

• Si la seule option est de réduire un fichier, alors quand dois-je le faire? Puis-je le faire lorsqu'une transaction active est activée? [Environnement de production], pour me guider mais j'ai besoin de libérer de l'espace. J'ai un grand entrepôt de données qui traite des millions de données tous les jours

Veuillez ne pas rétrécir aucun fichier de données ou journal. Je ne le recommanderais pas. Si vous voulez vraiment rétrécir UNE FOIS pour récupérer de l'espace et que vous n'avez pas d'autre option que de rétrécir, vous pourriez aussi bien l'essayer. Mais rappelez-vous encore une fois que vous devez reconstruire tous les index fragmentés après avoir terminé la réduction. Vous pouvez essayer la méthode donnée par Paul dans Cet article qui dit de ne pas rétrécir et donne une alternative de rétrécissement.

Vous ne pouvez réduire le fichier journal qu'une seule fois, mais n'oubliez pas que le fichier journal a augmenté parce que vous avez exécuté une transaction qui l'a forcé à se développer, c'est donc essentiellement votre erreur et non le fichier journal des transactions. Au lieu de tout ce processus de croissance et de réduction, pourquoi ne pas préallouer une certaine quantité d'espace au fichier journal afin qu'il puisse éviter les événements de croissance automatique

Autre chose

enter image description here

La configuration ci-dessus est très mauvaise. La croissance automatique de 1 Mo pour le fichier de données est susceptible de provoquer des problèmes. Pour définir la valeur correcte, veuillez lire l'article Paramètres de croissance automatique . Cela vous aidera à calculer le paramètre de croissance automatique correct.

5
Shanky

Si possible, vous devez réduire la quantité de données modifiées par transaction. Engagez-vous plus souvent avec moins de données. Sinon, augmentez encore la taille du journal. Si vous manquez d'espace, vous devez augmenter.

0
leancz