web-dev-qa-db-fra.com

SQL Server tronque les journaux de transactions avec des sauvegardes de copie uniquement

J'ai une base de données qui est réglée sur le mode de récupération "complet". La base de données ne montre pas qu'une sauvegarde du journal des transactions a été effectuée. backup_finish_date Affiche null pour mes journaux.

Je fais des sauvegardes tous les soirs de la base de données complète (copie uniquement). La sauvegarde semble tronquer le journal des transactions. Le journal des transactions fait environ 40 Go. Avant la sauvegarde, elle est pleine à 75%. Lorsque la sauvegarde s'exécute, elle n'est remplie qu'à 1%. Utilisation de DBCC SQLPERF(logspace).

Le sys.databases Affiche: recovery_model_desc FULL, log_reuse_wait 0, log_reuse_wait_desc NOTHING.

J'ai une copie de cette base de données sur un autre serveur, même configuration, mais les journaux de transactions ne sont PAS tronqués. En pleine croissance.

Le sys.database Sur la copie affiche FULL, 2, LOG_BACKUP. C'est ce à quoi je m'attendrais.

Je comprends que la copie de ma base de données est la façon dont les choses devraient fonctionner. Mais j'aimerais savoir pourquoi/comment les journaux sont tronqués dans mon environnement de production.

Pas de mise en miroir, pas d'expédition de journal de transactions.

7
Bob Larsen

Je vous recommande d'utiliser le code dans l'une des deux réponses existantes pour valider que les t-logs ne sont pas pris. Selon l'accès dont disposent vos utilisateurs, quelqu'un peut effectuer des sauvegardes à votre insu.

Il y avait un commentaire et un lien par Denis Rubashkin parlant de Pseudo-Simple SQL Server Recovery Model Essentiellement, il dit que si vous êtes en pleine récupération et que vous n'avez jamais effectué de sauvegarde complète ( ou autrement perturbé la chaîne LSN), SQL sait qu'il n'y a aucun moyen de récupérer, et il ne sauvegarde pas les t-logs.

Mais compte tenu de votre description:

la sauvegarde semble tronquer le journal des transactions. Le journal des transactions fait environ 40 Go. Avant la sauvegarde, elle est pleine à 75%. Lorsque la sauvegarde s'exécute, elle n'est pleine qu'à 1%.

Je ne pense pas que l'une des deux possibilités ci-dessus soit la cause de votre problème.

Je soupçonne que votre travail de sauvegarde définit la base de données sur SIMPLE récupération à un moment donné du processus, cela effacerait les t-logs. Il redéfinit ensuite la base de données sur FULL recovery. Ce scénario créerait les symptômes que vous voyez.

Parcourez le code de sauvegarde, si vous constatez qu'une modification de SIMPLE et de nouveau en FULL se produit, vous voudrez changer quelque chose. Soit laisser la base de données dans SIMPLE recovery tout le temps, soit effectuer des sauvegardes régulières de t-log. Le choix que vous faites est une décision commerciale, en fonction de vos objectifs de récupération.

Il n'y a aucune bonne raison d'être en pleine récupération si vous n'effectuez pas de sauvegardes de t-log.

Modifier Je viens de remarquer un autre indice dans votre question.

tous les soirs de la base de données complète (copie uniquement).

Pourquoi effectuez-vous des sauvegardes Full (Copy Only)? La seule raison pour cela est que vous effectuez une seule sauvegarde et que vous souhaitez conserver la chaîne de sauvegarde lorsque vous comptez sur des sauvegardes différentielles pour votre récupération. Voir Sauvegardes en copie seule

Cet indice suggère qu'il existe des sauvegardes complètes, différentielles et t-log que vous ne connaissez pas, il suggère que quiconque a écrit votre travail de sauvegarde nocturne en tant que copy only était conscient des différences et souhaitait conserver la chaîne de sauvegarde. Si tel est le cas, je m'attends à ce que les t-logs soient pris plusieurs fois par jour, les scénarios normaux sont Fulls une fois par semaine, Differentials les 6 autres jours par semaine, et t-logs régulièrement tout au long de la journée.

Ou cela pourrait signifier que la personne qui a mis la modification à SIMPLE et à nouveau à FULL l'a simplement ajoutée au hasard parce qu'elle ne connaissait pas la raison ou l'impact de copy only Soit.

11
James Jenkins

Ma réponse à Comment obtenir les heures de début et de fin des sauvegardes et des restaurations? contient un script qui récupérera les informations de sauvegarde de toutes les bases de données sur une instance SQL Server.

--------------------------------------------------------------------------------- 
--      Database Backups for all databases For Previous Week 
--------------------------------------------------------------------------------- 
SELECT  

/* Columns for retrieving information */

   -- CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS SRVNAME, 
   msdb.dbo.backupset.database_name,  
   msdb.dbo.backupset.backup_start_date,  
   msdb.dbo.backupset.backup_finish_date, 
   msdb.dbo.backupset.expiration_date, 
   CASE msdb..backupset.type  
       WHEN 'D' THEN 'Full'  
       WHEN 'I' THEN 'Diff'
       WHEN 'L' THEN 'Log'  
   END AS backup_type,  
   -- msdb.dbo.backupset.backup_size / 1024 / 1024 as [backup_size MB],  
   -- msdb.dbo.backupmediafamily.device_type,
   msdb.dbo.backupmediafamily.physical_device_name,
   -- msdb.dbo.backupmediafamily.logical_device_name,
   -- msdb.dbo.backupset.name AS backupset_name, 
   msdb.dbo.backupset.description,
   msdb.dbo.backupset.is_copy_only,
   msdb.dbo.backupset.is_snapshot,   
   msdb.dbo.backupset.first_lsn,
   msdb.dbo.backupset.last_lsn,
   msdb.dbo.backupset.database_backup_lsn,
   msdb.dbo.backupset.checkpoint_lsn,
   msdb.dbo.backupset.differential_base_lsn,
   msdb.dbo.backupset.fork_point_lsn,
   msdb.dbo.backupmediaset.name,
   msdb.dbo.backupmediaset.software_name,
   msdb.dbo.backupset.user_name,
   'EOR'

FROM   msdb.dbo.backupmediafamily  
   INNER JOIN msdb.dbo.backupset 
   ON msdb.dbo.backupmediafamily.media_set_id = msdb.dbo.backupset.media_set_id  
   INNER JOIN msdb.dbo.backupmediaset
   on msdb.dbo.backupmediaset.media_set_id = backupmediafamily.media_set_id


/* ----------------------------------------------------------------------------
        Generic WHERE statement to simplify selection of more WHEREs    
-------------------------------------------------------------------------------*/
WHERE 1 = 1
AND msdb.dbo.backupset.database_name = 'YOUR_DATABASE'
ORDER BY  
          2 desc, -- backup start
          1,      -- database name
          3 desc  -- backup end

Remplacer YOUR_DATABASE avec le nom de votre base de données.

Exécutez ce script sur votre instance SQL Server. Vous pouvez ajouter des conditions WHERE supplémentaires pour limiter la recherche de votre base de données et d'autres informations.

Maintenant, si le msdb.dbo.backupmediafamily.physical_device_name la colonne contient d'autres informations que l'appareil que vous utilisez pour votre copy_only sauvegarde, c'est le signe qu'une autre solution effectue des sauvegardes.

Dans un environnement de production, je m'attendrais à voir des entrées pour une solution d'entreprise similaire à 287899b2-d08e-40c3-a83d-677d898b6671 (qui est un identifiant de solution de sauvegarde pour un lecteur de bande virtuel).

Certains outils placent un commentaire dans le msdb.dbo.backupset.description colonne qui pourrait fournir une indication de ce qui se passe.

Voyez ce que vous pouvez récupérer à partir de votre historique de sauvegarde.

5
John aka hot2use

Il y a certainement des sauvegardes de journaux en cours d'exécution. Le mode de récupération complète ferait croître vos journaux au point qu'il n'y aurait plus de place sur le disque. Veuillez utiliser le script ci-dessous pour trouver les sauvegardes de journaux de votre base de données:

select a.database_name,a.backup_size,backup_start_date,backup_finish_date,b.physical_device_name,a.type from msdb..backupset a  
inner join msdb..backupmediafamily b on a.media_set_id = b.media_set_id
where a.database_name = 'YourDatabaseName' and a.type = 'L'
order by backup_start_date desc
3
Ramakant Dadhichi