Установить простой режим восстановления и сжать файлы журнала для всех пользовательских баз данных

8

Я надеюсь, что вы можете указать мне в правильном направлении. Я не частый пользователь T-SQL, но я немного погуглил и нашел скрипт ниже. Я немного исправил сценарий.

Я хочу, чтобы скрипт:

  1. Выбрать все базы данных, кроме системных БД.
  2. Чтобы восстановить простой.
  3. Чтобы сжать файлы журнала для каждого БД (.ldf), кроме системного БД

Сценарий:

USE MASTER
declare
@isql varchar(2000),
@dbname varchar(64)

declare c1 cursor for select name from master..sysdatabases where name not in ('master','model','msdb','tempdb','ReportServer','ReportServerTempDB')
open c1
fetch next from c1 into @dbname
While @@fetch_status <> -1
    begin
    select @isql = 'ALTER DATABASE @dbname SET RECOVERY SIMPLE'
    select @isql = replace(@isql,'@dbname',@dbname)
    print @isql
    exec(@isql)
    select @isql='USE @dbname checkpoint'
    select @isql = replace(@isql,'@dbname',@dbname)
    print @isql
    exec(@isql)
    select @isql='DBCC SHRINKFILE @dbname.ldf'
    select @isql = replace(@isql,'@dbname',@dbname)
    print @isql
    exec(@isql)

    fetch next from c1 into @dbname
    end
close c1
deallocate c1
Arviddk
источник
Почему, почему, почему? И что такое «правильное направление»? Скрипт не работает? Если так, то как? Вы получаете сообщение об ошибке? Что это? Вероятно, нужна команда USE в последнем блоке. Но опять же: почему, почему, почему?
Аарон Бертран
Потому что файлы .ldf занимают 70% дискового пространства на сервере. Но если вы знаете лучший способ, пожалуйста, просветите меня. Я не знаю, работает ли скрипт, я просто не могу его запустить. Я должен быть уверен, что это работает в первую очередь, поскольку это производственная среда.
Арвиддк
У вас нет среды разработки или тестирования, где вы можете это проверить? Честно говоря, я бы ничего не взял отсюда, независимо от того, кто написал это, и применил бы это к производству, основываясь только на заверениях незнакомцев в Интернете ...
Аарон Бертран
@Arviddk Знаете ли вы, каковы последствия изменения модели восстановления с FULL / BULK LOGGED на SIMPLE? Если вы знаете, продолжайте и сделайте это.
BuahahaXD
Я просто хотел прокомментировать, почему будущие читатели, возможно, хотят сделать то же самое. Мы привыкли делать полное резервное копирование SQL с резервными копиями журналов транзакций. С тех пор мы перешли на использование Dell AppAssure для создания резервных копий, что позволяет нам не создавать резервных копий журнала транзакций. Теперь у нас остались сотни баз данных на нескольких серверах, по-прежнему без всякой причины заполненные терабайтами файлов LDF. Это влияет на резервное копирование / восстановление, а также на другие вещи, связанные с репликацией и тому подобным.
Торин

Ответы:

13

Используйте Script для сжатия файлов журнала всех баз данных, кроме системных.

USE MASTER   
GO    
SET QUOTED_IDENTIFIER ON  
GO  
SET ARITHABORT ON  
GO  

DECLARE @DBName NVARCHAR(255),@LogicalFileName NVARCHAR(255),@DBRecoveryDesc Varchar(200)  

DECLARE DatabaseList CURSOR   
FOR   
SELECT name,recovery_model_desc  
FROM sys.databases  
WHERE state_desc = 'ONLINE'  
AND is_read_only = 0  
and database_id>4  
ORDER BY name  

OPEN DatabaseList  
FETCH NEXT FROM DatabaseList INTO @DBName,@DBRecoveryDesc  
WHILE @@FETCH_STATUS = 0     
BEGIN   

SET @LogicalFileName=(SELECT top 1 name FROM sys.master_files AS mf WHERE DB_NAME(database_id)=@DBName and type_desc='LOG')  

If @DBRecoveryDesc='Full'  
Begin  
     Print('Use ['+@DBName+'] 
            GO  

           ALTER DATABASE ['+@DBName+'] SET RECOVERY SIMPLE WITH NO_WAIT
           GO   

            DBCC SHRINKFILE ('''+@LogicalFileName+''',10)  
            GO  

            ALTER DATABASE ['+@DBName+'] SET RECOVERY FULL WITH  NO_WAIT
            GO ')  
Print '----------------------------------------------------------- '  
END  

If @DBRecoveryDesc='Simple'  
Begin   
     Print('Use ['+@DBName+']  
            GO  

            DBCC SHRINKFILE ('''+@LogicalFileName+''',10)    
            GO    
 ')  
Print '----------------------------------------------------------- '

END

         FETCH NEXT FROM DatabaseList INTO @DBName,@DBRecoveryDesc
      END  
CLOSE DatabaseList  
DEALLOCATE DatabaseList
AA.SC
источник
Сначала я думал, что выполнение ------...приведет к ошибке, но подсветка синтаксиса дала мне подсказку о том, что на самом деле произойдет. Ухоженная!
ta.speot.is
Спасибо, я собираюсь попробовать это в нашей среде разработчиков и подтолкнуть к продукту
Торин
Вы должны добавить «DBCC SHRINKFILE ('' '+ @ LogicalFileName +' _ Log '', 10) GO", иначе база данных журнала не будет уменьшена.
Андреас Рем
5

У меня всегда было такое отвращение к курсорам, что я написал это, поскольку я могу лучше понять это. Это полностью основано на ответе AA.SC (спасибо, кстати), просто так, как я думаю. Если это сочетается с тем, что думают другие, тогда отлично. Обратите внимание, я не вернул его в режим полного восстановления после этого.

SELECT 
'--', d.name dbName, d.recovery_model, d.recovery_model_desc , mf.name LogicalFileName,
'
use [' + d.name + ']

if(' + cast(d.recovery_model as varchar(5)) + ' = 1)
BEGIN
    ALTER DATABASE ['+ d.name +'] SET RECOVERY SIMPLE WITH NO_WAIT
END
GO 
DBCC SHRINKFILE (''' + mf.name  +''',10)  
GO  
'
FROM sys.databases d
join sys.master_files mf
    on d.database_id = mf.database_id
    and mf.type_desc = 'LOG' 
WHERE d.state_desc = 'ONLINE'  
AND d.is_read_only = 0  
and d.database_id > 4 
--and d.recovery_model = 1
ORDER BY d.name 
Марк Рулло
источник