Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment effacer le journal des transactions SQL Server ?

La réduction de la taille d'un fichier journal devrait vraiment être réservée aux scénarios où il a rencontré une croissance inattendue que vous ne vous attendez pas à reproduire. Si le fichier journal atteint à nouveau la même taille, il n'y a pas grand-chose à faire en le réduisant temporairement. Maintenant, en fonction des objectifs de récupération de votre base de données, voici les actions que vous devez entreprendre.

Tout d'abord, effectuez une sauvegarde complète

N'apportez jamais de modifications à votre base de données sans vous assurer de pouvoir la restaurer en cas de problème.

Si vous vous souciez de la récupération ponctuelle

(Et par récupération ponctuelle, je veux dire que vous vous souciez de pouvoir restaurer autre chose qu'une sauvegarde complète ou différentielle.)

Vraisemblablement votre base de données est en FULL mode de récupération. Si ce n'est pas le cas, assurez-vous qu'il l'est :

ALTER DATABASE testdb SET RECOVERY FULL;

Même si vous effectuez des sauvegardes complètes régulières, le fichier journal grandira et grandira jusqu'à ce que vous effectuiez un journal sauvegarde - c'est pour votre protection, pas pour grignoter inutilement votre espace disque. Vous devez effectuer ces sauvegardes de journaux assez fréquemment, en fonction de vos objectifs de récupération. Par exemple, si vous avez une règle métier qui stipule que vous ne pouvez pas vous permettre de perdre plus de 15 minutes de données en cas de sinistre, vous devez avoir une tâche qui sauvegarde le journal toutes les 15 minutes. Voici un script qui générera des noms de fichiers horodatés en fonction de l'heure actuelle (mais vous pouvez également le faire avec des plans de maintenance, etc., mais ne choisissez aucune des options de réduction dans les plans de maintenance, elles sont horribles).

DECLARE @path NVARCHAR(255) = N'\\backup_share\log\testdb_' 
  + CONVERT(CHAR(8), GETDATE(), 112) + '_'
  + REPLACE(CONVERT(CHAR(8), GETDATE(), 108),':','')
  + '.trn';

BACKUP LOG foo TO DISK = @path WITH INIT, COMPRESSION;

Notez que \\backup_share\ doit se trouver sur une autre machine qui représente un autre périphérique de stockage sous-jacent. Les sauvegarder sur la même machine (ou sur une machine différente qui utilise les mêmes disques sous-jacents, ou une machine virtuelle différente qui se trouve sur le même hôte physique) ne vous aide pas vraiment, car si la machine explose, vous avez perdu votre base de données et ses sauvegardes. En fonction de votre infrastructure réseau, il peut être plus judicieux de sauvegarder localement, puis de les transférer vers un emplacement différent dans les coulisses ; dans les deux cas, vous souhaitez les retirer de la machine de base de données principale le plus rapidement possible.

Maintenant, une fois que vous avez exécuté des sauvegardes de journaux régulières, il devrait être raisonnable de réduire le fichier journal à quelque chose de plus raisonnable que tout ce qu'il a fait jusqu'à présent. Cela n'est pas signifie exécuter SHRINKFILE maintes et maintes fois jusqu'à ce que le fichier journal atteigne 1 Mo - même si vous sauvegardez fréquemment le journal, il doit toujours prendre en charge la somme de toutes les transactions simultanées qui peuvent se produire. Les événements de croissance automatique des fichiers journaux sont coûteux, car SQL Server doit mettre à zéro les fichiers (contrairement aux fichiers de données lorsque l'initialisation instantanée des fichiers est activée), et les transactions des utilisateurs doivent attendre pendant que cela se produit. Vous voulez faire le moins possible cette routine de croissance-rétrécissement-croissance-rétrécissement, et vous ne voulez certainement pas faire payer vos utilisateurs pour cela.

Notez que vous devrez peut-être sauvegarder le journal deux fois avant qu'une réduction ne soit possible (merci Robert).

Vous devez donc trouver une taille pratique pour votre fichier journal. Personne ici ne peut vous dire ce que c'est sans en savoir beaucoup plus sur votre système, mais si vous avez fréquemment réduit le fichier journal et qu'il a recommencé, un bon filigrane est probablement 10 à 50 % plus élevé que le plus grand qu'il ait été . Supposons que cela atteigne 200 Mo et que vous souhaitiez que tous les événements de croissance automatique ultérieurs soient de 50 Mo, vous pouvez alors ajuster la taille du fichier journal de cette façon :

USE [master];
GO
ALTER DATABASE Test1 
  MODIFY FILE
  (NAME = yourdb_log, SIZE = 200MB, FILEGROWTH = 50MB);
GO

Notez que si le fichier journal fait actuellement> 200 Mo, vous devrez peut-être d'abord exécuter ceci :

USE yourdb;
GO
DBCC SHRINKFILE(yourdb_log, 200);
GO

Si vous ne vous souciez pas de la récupération ponctuelle

S'il s'agit d'une base de données de test et que vous ne vous souciez pas de la récupération à un moment donné, vous devez vous assurer que votre base de données est en SIMPLE mode de récupération.

ALTER DATABASE testdb SET RECOVERY SIMPLE;

Mettre la base de données en SIMPLE le mode de récupération s'assurera que SQL Server réutilise des parties du fichier journal (essentiellement en supprimant progressivement les transactions inactives) au lieu de croître pour conserver un enregistrement de tous transactions (comme FULL récupération jusqu'à ce que vous sauvegardiez le journal). CHECKPOINT les événements aideront à contrôler le journal et à s'assurer qu'il n'a pas besoin de croître à moins que vous ne génériez beaucoup d'activité t-log entre CHECKPOINT s.

Ensuite, vous devez vous assurer que cette croissance du journal est vraiment due à un événement anormal (par exemple, un nettoyage de printemps annuel ou la reconstruction de vos plus gros index), et non à une utilisation normale et quotidienne. Si vous réduisez le fichier journal à une taille ridiculement petite et que SQL Server doit simplement l'agrandir à nouveau pour s'adapter à votre activité normale, qu'avez-vous gagné ? Avez-vous pu utiliser cet espace disque que vous n'aviez libéré que temporairement ? Si vous avez besoin d'un correctif immédiat, vous pouvez exécuter ce qui suit :

USE yourdb;
GO
CHECKPOINT;
GO
CHECKPOINT; -- run twice to ensure file wrap-around
GO
DBCC SHRINKFILE(yourdb_log, 200); -- unit is set in MBs
GO

Sinon, définissez une taille et un taux de croissance appropriés. Comme dans l'exemple du cas de récupération ponctuelle, vous pouvez utiliser le même code et la même logique pour déterminer la taille de fichier appropriée et définir des paramètres de croissance automatique raisonnables.

Certaines choses que vous ne voulez pas faire

  • Sauvegarder le journal avec TRUNCATE_ONLY puis SHRINKFILE . D'une part, ce TRUNCATE_ONLY L'option est obsolète et n'est plus disponible dans les versions actuelles de SQL Server. Deuxièmement, si vous êtes en FULL modèle de récupération, cela détruira votre chaîne de journaux et nécessitera une nouvelle sauvegarde complète.

  • Détachez la base de données, supprimez le fichier journal et rattachez . Je ne peux pas souligner à quel point cela peut être dangereux. Votre base de données peut ne pas être sauvegardée, elle peut apparaître comme suspecte, vous devrez peut-être revenir à une sauvegarde (si vous en avez une), etc. etc.

  • Utilisez l'option "Réduire la base de données" . DBCC SHRINKDATABASE et l'option de plan de maintenance pour faire de même sont de mauvaises idées, surtout si vous n'avez vraiment besoin que de résoudre un problème de journal. Ciblez le fichier que vous souhaitez ajuster et ajustez-le indépendamment, en utilisant DBCC SHRINKFILE ou ALTER DATABASE ... MODIFY FILE (exemples ci-dessus).

  • Réduire le fichier journal à 1 Mo . Cela semble tentant car, hé, SQL Server me laissera le faire dans certains scénarios, et regardez tout l'espace qu'il libère ! Sauf si votre base de données est en lecture seule (et c'est le cas, vous devez la marquer comme telle en utilisant ALTER DATABASE ), cela entraînera absolument de nombreux événements de croissance inutiles, car le journal doit prendre en charge les transactions en cours, quel que soit le modèle de récupération. Quel est l'intérêt de libérer temporairement cet espace, juste pour que SQL Server puisse le récupérer lentement et péniblement ?

  • Créer un deuxième fichier journal . Cela soulagera temporairement le lecteur qui a rempli votre disque, mais c'est comme essayer de réparer un poumon perforé avec un pansement. Vous devez traiter directement le fichier journal problématique au lieu de simplement ajouter un autre problème potentiel. À part rediriger une partie de l'activité du journal des transactions vers un autre lecteur, un deuxième fichier journal ne fait vraiment rien pour vous (contrairement à un deuxième fichier de données), car un seul des fichiers peut être utilisé à la fois. Paul Randal explique également pourquoi plusieurs fichiers journaux peuvent vous mordre plus tard.

Soyez proactif

Au lieu de réduire votre fichier journal à une petite quantité et de le laisser croître automatiquement à un petit rythme, réglez-le sur une taille raisonnablement grande (qui pourra accueillir la somme de votre plus grand ensemble de transactions simultanées) et définissez une croissance automatique raisonnable paramètre de secours, afin qu'il n'ait pas à croître plusieurs fois pour satisfaire des transactions uniques et qu'il soit relativement rare qu'il doive croître pendant les opérations commerciales normales.

Les pires paramètres possibles ici sont une croissance de 1 Mo ou une croissance de 10 %. Assez drôle, ce sont les valeurs par défaut pour SQL Server (dont je me suis plaint et demandé des modifications en vain) - 1 Mo pour les fichiers de données et 10% pour les fichiers journaux. Le premier est beaucoup trop petit de nos jours, et le second conduit à des événements de plus en plus longs à chaque fois (par exemple, votre fichier journal est de 500 Mo, la première croissance est de 50 Mo, la prochaine croissance est de 55 Mo, la prochaine croissance est de 60,5 Mo , etc. etc. - et sur les E/S lentes, croyez-moi, vous remarquerez vraiment cette courbe).

Autres lectures

S'il vous plaît ne vous arrêtez pas ici; alors que la plupart des conseils que vous voyez sur la réduction des fichiers journaux sont intrinsèquement mauvais et même potentiellement désastreux, certaines personnes se soucient davantage de l'intégrité des données que de la libération d'espace disque.

Un article de blog que j'ai écrit en 2009, lorsque j'ai vu apparaître quelques messages "Voici comment réduire le fichier journal".

Un article de blog que Brent Ozar a écrit il y a quatre ans, pointant vers plusieurs ressources, en réponse à un article de SQL Server Magazine qui ne devrait pas ont été publiés.

Un article de blog de Paul Randal expliquant pourquoi la maintenance t-log est importante et pourquoi vous ne devriez pas non plus réduire vos fichiers de données.

Mike Walsh a également une excellente réponse couvrant certains de ces aspects, y compris les raisons pour lesquelles vous ne pourrez peut-être pas réduire votre fichier journal immédiatement.