Mengatur mode pemulihan sederhana dan mengecilkan file log untuk semua database yang dibuat pengguna

8

Saya harap Anda bisa mengarahkan saya ke arah yang benar. Saya bukan pengguna T-SQL yang sering, tetapi saya melakukan beberapa pencarian google, dan menemukan skrip di bawah ini. Saya sedikit mengoreksi naskah.

Saya ingin skrip:

  1. Untuk memilih semua basis data, kecuali DB sistem.
  2. Untuk mengatur pemulihan menjadi sederhana.
  3. Untuk mengecilkan file log untuk setiap db (.ldf), kecuali sistem db

Naskah:

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
sumber
Mengapa mengapa mengapa? Apa itu "arah yang benar"? Apakah skrip tidak berfungsi? Jika ya, bagaimana caranya? Apakah Anda mendapatkan pesan kesalahan? Apa itu? Mungkin membutuhkan perintah USE di blok terakhir. Tetapi sekali lagi: Mengapa, mengapa, mengapa?
Aaron Bertrand
Karena file .ldf membutuhkan 70% ruang disk di server. Tetapi jika Anda tahu cara yang lebih baik, tolong beri tahu saya. Saya tidak tahu apakah skrip berfungsi, saya tidak bisa menjalankannya. Saya harus yakin itu berfungsi dulu, karena ini merupakan lingkungan produksi.
Arviddk
Anda tidak memiliki dev atau lingkungan pengujian di mana Anda dapat menguji ini? Terus terang saya tidak akan mengambil apa pun dari sini, terlepas dari siapa yang menulisnya, dan menerapkannya pada produksi hanya berdasarkan jaminan orang asing di Internet ...
Aaron Bertrand
@Arviddk Tahukah Anda apa konsekuensi dari mengubah model pemulihan dari FULL / BULK LOGGED ke SIMPLE? Jika Anda sadar, silakan dan lakukan itu.
BuahahaXD
Saya hanya ingin mengomentari mengapa untuk pembaca masa depan yang mungkin mencari untuk melakukan hal yang sama. Kami biasa melakukan backup SQL lengkap dengan backup log transaksi. Kami sejak itu beralih menggunakan Dell AppAssure untuk melakukan pencadangan yang menempatkan kami di tempat di mana kami tidak memerlukan pencadangan log transaksi. Sekarang kita dibiarkan dengan ratusan basis data di beberapa server masih diatur penuh dengan terabyte file LDF tanpa alasan. Ini mempengaruhi backup / mengembalikan serta hal-hal lain yang ada di sekitar itu, replikasi dan semacamnya.
Thorin

Jawaban:

13

Gunakan Skrip untuk Mengecilkan file Log dari semua database selain dari DB sistem.

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
sumber
Pada awalnya saya pikir mengeksekusi ------...akan menghasilkan kesalahan tetapi penyorotan sintaks memberi saya petunjuk tentang apa yang sebenarnya akan terjadi. Rapi!
ta.speot.is
Terima kasih, saya akan mencoba ini di lingkungan dev kami dan mendorong untuk mendorong
Thorin
Anda harus menambahkan "DBCC SHRINKFILE ('' '+ @ LogicalFileName +' _ Log '', 10) GO" - jika tidak, basis data log tidak akan menyusut.
Andreas Rehm
5

Saya selalu memiliki keengganan terhadap kursor, bahwa saya menulis ini karena saya bisa lebih memahaminya. Ini benar-benar didasarkan pada jawaban AA.SC (terima kasih ngomong-ngomong), hanya dengan cara yang menurut saya. Jika ini cocok dengan apa yang dipikirkan orang lain, maka hebat. Catatan, saya tidak mengembalikannya ke mode pemulihan penuh sesudahnya.

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 
Mark Rullo
sumber