Pourquoi le journal des transactions continue-t-il de croître en mode de récupération simple avec des sauvegardes nocturnes

24

Avant de marquer immédiatement comme doublon , j'ai lu pourquoi Mike Walsh Pourquoi le journal des transactions continue-t-il de croître ou de manquer d'espace? , mais je ne pense pas que cela ait répondu à ma situation. J'ai regardé à travers une douzaine de questions similaires, mais les questions pertinentes ont simplement dit "dupliquer" et ont pointé la question de Mike.

Détails: J'ai un tas de bases de données de ~ 500 Mo sur SQL Server 2008 R2, toutes en mode de récupération SIMPLE (pas mon choix), des sauvegardes complètes nocturnes, avec ~ 200 Mo de fichiers de données et ~ 300 Mo de fichiers journaux. Le journal n'atteint pas immédiatement 300 Mo, mais plutôt lentement au cours de quelques mois. Il n'y a aucune transaction ouverte sur aucun d'entre eux, du moins selon sp_who2 et le moniteur d'activité. Si je clique avec le bouton droit sur la base de données et sélectionne les propriétés, cela m'indique qu'il y a ~ 50 Mo d'espace libre. Particulièrement juste après une sauvegarde, le journal entier ne devrait-il pas être gratuit? En mode SIMPLE, le journal ne devrait-il pas être gratuit tant qu'il n'y a pas de transaction ouverte?

log_reuse_wait_descde sys.databasesdit dit "RIEN", qui sur la base de la question et réponse référencée ci-dessus dit qu'il ne devrait pas attendre quoi que ce soit pour réutiliser l'espace.

Si je fais «DBCC SHRINKFILE», le fichier journal se réduit à 1 Mo, il est donc prêt à récupérer l'espace. Je peux configurer quelque chose qui réduit les journaux chaque semaine et empêcher les choses de devenir hors de contrôle, mais je ne comprends pas pourquoi SQL Server me ferait faire cela.

Je peux comprendre s'il y avait une transaction folle qui avait besoin de 300 Mo pour la journaliser, mais nous ne faisons rien d'extrême, juste OLTP de base. D'après la question / réponse de Mike:

Modèle de récupération simple - Donc, avec l'introduction ci-dessus, il est plus facile de parler d'abord du modèle de récupération simple. Dans ce modèle, vous dites à SQL Server - je suis d'accord avec vous en utilisant votre fichier journal des transactions pour la récupération après incident et redémarrage (vous n'avez vraiment pas le choix là-bas .. Recherchez les propriétés ACID et cela devrait avoir un sens rapidement), mais une fois que vous n'avez pas vous en aurez plus besoin à des fins de récupération après un crash / redémarrage, continuez et réutilisez le fichier journal.

SQL Server écoute cette demande dans Simple Recovery et ne conserve que les informations dont il a besoin pour effectuer une récupération après panne / redémarrage. Une fois que SQL Server est sûr qu'il peut récupérer car les données sont durcies dans le fichier de données (plus ou moins), les données qui ont été durcies ne sont plus nécessaires dans le journal et sont marquées pour la troncature - ce qui signifie qu'elles sont réutilisées.

Il continue de dire que l'espace journal devrait être réutilisé, mais avec cette croissance lente au cours des mois, il ne semble pas que ce soit le cas.

Qu'est-ce que je rate? Quelque chose empêche-t-il SQL Server de reconnaître les données comme "renforcées" et de libérer le journal?

(modifier) Le rapport après action - AKA un peu de connaissance est dangereux

Après avoir découvert qu'il s'agissait d'une "question populaire", j'ai eu l'impression que je devais une explication de ce qui s'est passé il y a 7 mois et de ce que j'ai appris pour, espérons-le, sauver d'autres personnes du chagrin.

Tout d'abord, l'espace disponible que vous voyez dans SSMS lorsque vous affichez les propriétés d'une base de données est l'espace disponible dans le fichier de données. Vous pouvez le voir en exécutant ce qui suit sur une base de données, et vous constaterez que l'espace disponible signalé par SSMS est la différence entre FileSizeMB et UsedSpaceMB:

SELECT
    DB.name,
    MF.physical_name,
    MF.type_desc AS FileType,
    MF.size * 8 / 1024 AS FileSizeMB,
    fileproperty(MF.name, 'SpaceUsed') * 8/ 1024 AS UsedSpaceMB,
    mf.name LogicalName
FROM
    sys.master_files MF
    JOIN sys.databases DB ON DB.database_id = MF.database_id
WHERE   DB.name = 'yourdatabasename'

Cela a confirmé que dans des circonstances normales, nous utilisions très peu d'espace de journal (20 Mo ou moins), mais cela nous amène au deuxième élément ...

Deuxièmement, ma perception de la croissance des grumes était celle de lentement au fil du temps. Cependant, en réalité, les journaux augmentaient rapidement les nuits où le gars responsable de l'application des correctifs pour cette application tierce appliquait des correctifs. Le correctif a été effectué en une seule transaction, donc selon le correctif, les données de 200 Mo nécessitaient 300 Mo de journal. La clé du suivi a été la requête d'Aaron Bertrand sur https://sqlblog.org/2007/01/11/reviewing-autogrow-events-from-the-default-trace

DECLARE @path NVARCHAR(260);

SELECT 
    @path = REVERSE(SUBSTRING(REVERSE([path]), 
    CHARINDEX('\', REVERSE([path])), 260)) + N'log.trc'
FROM    sys.traces
WHERE   is_default = 1;

SELECT 
   DatabaseName,
   [FileName],
    SPID,
    Duration,
    StartTime,
    EndTime,
    FileType = CASE EventClass 
       WHEN 92 THEN 'Data'
       WHEN 93 THEN 'Log'
    END
FROM sys.fn_trace_gettable(@path, DEFAULT)
WHERE
    EventClass IN (92,93)
ORDER BY
    StartTime DESC;

Cela montrait que le journal augmentait certains soirs, lorsque le client n'utilisait pas la base de données. Cela a conduit à la conversation avec le gars appliquant les patchs et la réponse au mystère.

Merci encore pour les personnes qui m'ont aidé à obtenir la réponse.

DerekCate
la source
En fait, j'ai moi-même observé un phénomène similaire dans l'une des bases de données des sites de mes clients avec un modèle de récupération SIMPLE. Les journaux ne poussent pas (encore, de toute façon), mais l'espace utilisé dans les fichiers journaux ne se développent par un petit peu tous les soirs. Et cela se produit lorsque la sauvegarde de la base de données s'exécute. Je n'ai pas encore compris ce qui en est la cause ni si c'est un problème ou non.
RBarryYoung

Réponses:

20

Il nous est impossible de deviner ce qui en est la cause, mais SQL Server ne fait pas que développer un fichier journal à 300 Mo pour le diable, il atteint 300 Mo car à un moment donné depuis votre dernière opération de réduction, il en avait besoin beaucoup d'espace de journal (que ce soit en raison d'une grosse transaction unique ou de beaucoup de petites transactions simultanées). Vous devez suivre les événements de croissance du fichier journal (j'en ai parlé ici et ici ) pour essayer de préciser quand ou pourquoi cela se produit (également si le paramètre de croissance du fichier journal est de 300 Mo ou quelque chose, il augmentera de 300 Mo dès qu'il a besoin de plus de 1 Mo d'espace pour accueillir les transactions actives).

Quoi qu'il en soit, pourquoi pensez-vous que vous devez réduire le fichier journal une fois qu'il a atteint 300 Mo? Avez-vous réellement lu toutes les réponses, à fond, à la question de Mike ? Le fichier journal ne va PAS se réduire de lui-même, car la réduction du fichier journal à 1 Mo - juste pour qu'il puisse augmenter à nouveau lors de vos transactions les plus importantes - est une perte de temps totale. Qu'allez-vous faire de tout cet espace libre en attendant?

Aaron Bertrand
la source
Je ne pense pas que nous faisons quoi que ce soit qui nécessiterait 300 Mo de journal, mais même si nous le faisions, une fois cela fait, cela n'apparaîtrait-il pas comme de l'espace libre sur la base de données? Lorsque vous regardez les propriétés de la base de données dans SQL Server Management Studio, la taille est la taille des données et du journal, et je m'attendrais à ce que l'espace libre soit l'espace libre sur les données et le journal. L'espace libre dans le journal n'apparaît-il pas? Le fait qu'il ne s'affiche pas comme gratuit semblait être toujours utilisé, mais il n'y avait aucune activité sur la base de données.
DerekCate
1
Non, une fois terminé, il ne devient pas automatiquement de l'espace libre. Les transactions validées ne sont pas remises à zéro, leur espace est simplement marqué comme disponible pour réutilisation.
Aaron Bertrand
1
@DerekCate "Je ne pense pas que nous fassions quoi que ce soit qui nécessiterait 300 Mo de journal" ... Vous seriez surpris, il ne faut pas grand-chose pour bloquer la réutilisation du journal des transactions. Ne pensez pas à cela en termes de quantité de charge de travail, car ce n'est pas toujours la cause.
Thomas Stringer
Ok, donc juste pour confirmer que je comprends bien, le journal de 300 Mo, même s'il n'est pas actuellement nécessaire, ne s'affichera pas comme espace libre, mais sera réutilisé. Et à un moment donné, il avait besoin de 300 Mo pour gérer certaines transactions. Ok, de nouvelles choses à étudier. Merci!
DerekCate
1
Une autre chose à considérer: un point de contrôle automatique pour une base de données de récupération simple n'est mis en file d'attente que lorsque le journal est déjà rempli à 70%. Ainsi, vous n'aurez peut-être pas besoin de toute cette activité de journal pour générer une croissance, selon le moment.
Paul White dit GoFundMonica
6

Tous vos tests actuels ( DBCC SHRINKFILE, log_reuse_wait_desc) sont simplement ce droit prouvant maintenant vous réutilisez les fichiers journaux virtuels du journal des transactions de façon appropriée. Mais lorsque vos événements de croissance automatique se produisent sur votre fichier journal de transactions, c'est une réaction au fait que le journal ne peut pas être réutilisé.

Souvent, ce n'est pas une condition permanente (exactement à quoi cela vous semble en ce moment avec le manque de symptômes que vous voyez actuellement). Il existe une poignée de choses qui pourraient provoquer ce comportement, même dans le modèle de récupération simple.

Le mieux serait de configurer un travail de collecte de données pour extraire régulièrement le log_reuse_wait_descpour votre base de données et de le consigner régulièrement quelque part. Ensuite, vous devriez être en mesure de rétroconcevoir ce qui cause le manque de réutilisation des journaux.

Il continue de dire que l'espace journal devrait être réutilisé, mais avec cette croissance lente au cours des mois, il ne semble pas que ce soit le cas.

Comme je l'ai indiqué ci-dessus, ce n'est généralement pas une condition continue qui provoque le manque de réutilisation du journal des transactions (sauf quelques cas de coin, comme des transactions mal construites), vous devez donc déterminer les moments où cela se produit. La collecte légère des données de diagnostic devrait être un bon début.

Thomas Stringer
la source
S'il voit 50 Mo d'espace libre et un journal de 300 Mo, fn_DBLOG () lui donnerait-il un aperçu de ce qui augmentait la taille de son journal?
Kenneth Fisher
0

Le rétrécissement automatique est-il activé sur les bases de données? Et / ou avez-vous des plans de maintenance planifiés effectuant des reconstructions d'index?

Un rétrécissement automatique suivi d'une maintenance d'index produira un volume important de journaux.

La maintenance d'index en elle-même produira également un volume de journal important, s'il existe des problèmes de conception de base de données comme des index clusterisés sur les GUID.

Pete
la source
La réduction automatique n'est pas activée sur les bases de données, nous cherchons à éviter la fragmentation de l'index brentozar.com/archive/2009/08/… . Nous effectuons des vérifications d'intégrité hebdomadaires, mais je ne pense pas qu'il y ait de reconstruction d'index dans le cadre de cela, je vais devoir examiner cela. En dehors de cela, pas de GUID, chaque table a une colonne d'identité qui est la clé primaire.
DerekCate
-3
 create table #dblog (Databasename varchar(100),
                     logsize float,
                     logspace%] float,
                     [Status] int)

 insert into #dblog
 EXEC ('DBCC sqlperf(logspace)') 

 select * from #dblog

 alter table #dblog 
 add [lgspace used GB] float;

 update #dblog 
 set [lgspace used GB ] = (logsize*[logspace%]/1024)

 update #dblog 
 set [logsize] =([logsize]/1024)

 alter table #dblog 
 drop column [Status];

 select * from #dblog

 drop table #dblog
Madhav narayan thalambedu kuma
la source