J'ai hérité d'une base de données de 10 Go avec un journal de 80 Go [seulement 3% d'utilisation selon DBCC SQLPERF (logspace)]. Il semble prudent de supposer que la croissance du journal extrême était due à des problèmes de longue date avant d'être embauché.
Le primaire a un travail de sauvegarde d'expédition de journal qui fonctionne toutes les 15 minutes. Le primaire a copier et restaurer des travaux qui fonctionnent toutes les 15 minutes.
Lorsque j'essaie de réduire le journal, je reçois "Impossible de réduire le fichier journal 2 (Databasename_Log) car le fichier journal logique situé à la fin du fichier est utilisé." Je l'ai réessayé plusieurs fois 15 minutes de distance et même des jours d'intervalle, mais obtenez toujours le même résultat.
DBCC Loginfo affiche 784 VLFS, avec seulement les premiers 245 et la dernière avec un statut de 2. P_WhoisActive montre que la transaction ouverte la plus longue est exécutée pendant moins de 2 heures (de longues transactions ne sont pas inhabituelles ici en raison d'une tierce partie Microsoft Application d'accès avec ODBC Problèmes de pilote).
Comment puis-je rétrécir avec succès ce journal (sans créer de panne pour les utilisateurs)?
Merci, marque
La solution la plus simple à ce problème consiste à définir la base de données à une simple récupération, rétrécissez le journal, puis le remettez-le à la récupération complète. Dans T-SQL, ce serait:
ALTER DATABASE [database] SET RECOVERY SIMPLE WITH NO_WAIT
DBCC SHRINKFILE([logfilename], 1)
ALTER DATABASE [database] SET RECOVERY FULL WITH NO_WAIT
Changer la base de données en une récupération simple peut entraîner une réplication des transactions, mais si elle est programmée pendant les heures d'arrêt, il devrait rétrécir le journal et revenir à la récupération complète sans effets secondaires.
Si cela est inacceptable, vous pouvez utiliser la procédure SP_REPLDONE stockée pour marquer manuellement les transactions comme distribué et réinitialiser l'état de la réplication des transactions non valides:
EXEC sp_repldone @xactid = NULL, @xact_segno = NULL, @numtrans = 0, @time = 0, @reset = 1
Vous pouvez potentiellement exécuter un script tel que celui-ci pour tenter l'opération de rétrécissement une fois par minute jusqu'à ce qu'il se termine ou fonctionne de 1 000 fois. comme toujours, utilisez vos propres risques - et testez-le d'abord sur un environnement de non-production.
USE tempdb; /* CHANGE THIS TO DESIRED DATABASE */
GO
DECLARE @DesiredSizeInMB INT;
SET @DesiredSizeInMB = 1;
DECLARE @T TABLE (
CurrentSize BIGINT
);
DECLARE @LogFileName VARCHAR(255);
DECLARE @LoopCount INT;
DECLARE @MaxLoops INT;
DECLARE @OK BIT;
SELECT @LogFileName = df.name
FROM sys.database_files df
WHERE df.type_desc = 'LOG';
SET @LoopCount = 0;
SET @MaxLoops = 1000;
WHILE @LoopCount < @MaxLoops
BEGIN
SET @OK=1;
BEGIN TRY
DELETE FROM @T;
INSERT INTO @T
SELECT size * 8192 / 1048576E0
FROM sys.database_files df
WHERE df.type_desc = 'LOG';
DBCC SHRINKFILE (@LogFileName, @DesiredSizeInMB);
/* If the now-current size of the log file is with 1MB of the target size, break */
IF (SELECT CurrentSize * 8192 / 1048576E0 FROM @T) <= @DesiredSizeInMB + 1
BREAK;
ELSE
SET @OK = 0;
END TRY
BEGIN CATCH
SET @OK=0;
PRINT ERROR_MESSAGE();
END CATCH
IF @OK = 1 BREAK; /* IF the command didn't fail, then exit the loop */
WAITFOR DELAY '00:00:30'
SET @LoopCount = @LoopCount +1;
END
Lors du test de mon plan de sauvegarde sur un serveur de test VM qui a été déconnecté du réseau, j'exécutions une sauvegarde, puis utilisait la commande rétractable uniquement. J'utilise un modèle de récupération simple, je devais toujours forcer le réglage de la base de données en mode simple, alors seulement je pourrais réduire mes journaux T. La conclusion semble que si vous avez une base de données dans un modèle de récupération simple, vous n'avez pas encore besoin de ces commandes: Alter la base de données [base de données] SET RÉCUPÉRATION Simple avec No_Wait DBCC Strinkfile ([LOGFILEName], 1)