Đặt chế độ khôi phục đơn giản và thu nhỏ tệp nhật ký cho tất cả các cơ sở dữ liệu do người dùng tạo


8

Tôi hy vọng bạn có thể chỉ cho tôi đi đúng hướng. Tôi không phải là người thường xuyên sử dụng T-SQL, nhưng tôi đã thực hiện một số thao tác tìm kiếm trên google và tìm thấy tập lệnh bên dưới. Tôi sửa kịch bản một chút.

Tôi muốn kịch bản:

  1. Để chọn tất cả các cơ sở dữ liệu, ngoại trừ các DB hệ thống.
  2. Để thiết lập phục hồi thành đơn giản.
  3. Để thu nhỏ các tệp nhật ký cho mọi db (.ldf), ngoại trừ db hệ thống

Kịch bản:

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

Tại sao, tại sao, tại sao? Ngoài ra "đúng hướng" là gì? Liệu kịch bản không hoạt động? Nếu vậy thì thế nào? Bạn có nhận được một thông báo lỗi? Nó là gì? Có lẽ cần một lệnh USE trong khối cuối cùng. Nhưng một lần nữa: Tại sao, tại sao, tại sao?
Aaron Bertrand

Bởi vì các tệp .ldf chiếm 70% dung lượng đĩa trên máy chủ. Nhưng nếu bạn biết một cách tốt hơn, xin hãy khai sáng cho tôi. Tôi không biết nếu kịch bản hoạt động, tôi không thể chạy nó. Tôi phải chắc chắn rằng nó hoạt động đầu tiên, vì nó là một môi trường sản xuất.
Arviddk

Bạn không có môi trường phát triển hoặc thử nghiệm nơi bạn có thể kiểm tra điều này? Thành thật mà nói tôi sẽ không lấy bất cứ thứ gì từ đây, bất kể ai đã viết nó, và áp dụng nó vào sản xuất chỉ dựa trên sự đảm bảo của những người lạ trên Internet ...
Aaron Bertrand

@Arviddk Bạn có biết hậu quả của việc thay đổi mô hình khôi phục từ FULL / BULK LOGGED thành SIMPLE là gì không? Nếu bạn nhận thức được, hãy tiếp tục và làm điều đó.
BuahahaXD

Tôi chỉ muốn bình luận về lý do tại sao cho những độc giả tương lai có thể đang muốn làm điều tương tự. Chúng tôi đã từng thực hiện sao lưu SQL đầy đủ với sao lưu nhật ký giao dịch. Kể từ đó, chúng tôi đã thay đổi sử dụng Dell AppAssure để thực hiện sao lưu, đưa chúng tôi vào một nơi mà chúng tôi không cần sao lưu nhật ký giao dịch. Bây giờ chúng tôi còn lại với hàng trăm cơ sở dữ liệu trên nhiều máy chủ vẫn được đặt đầy đủ với terabyte tệp LDF mà không có lý do. Điều này ảnh hưởng đến sao lưu / khôi phục cũng như những thứ khác xung quanh đó, sao chép và như vậy.
Thorin

Câu trả lời:


13

Sử dụng Script để thu nhỏ các tệp nhật ký của tất cả các cơ sở dữ liệu khác với DB hệ thống.

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

Lúc đầu, tôi nghĩ việc thực thi ------...sẽ gây ra lỗi nhưng việc tô sáng cú pháp đã cho tôi một gợi ý về những gì thực sự sẽ xảy ra. Khéo léo!
ta.speot.is

Cảm ơn, tôi sẽ thử điều này trong môi trường nhà phát triển của chúng tôi và đẩy mạnh sản phẩm
Thorin

Bạn nên thêm "DBCC SHRINKFILE ('' '+ @ LogicalFileName +' _ Log '', 10) GO" - nếu không cơ sở dữ liệu nhật ký sẽ không bị thu hẹp.
Andreas Rehm

5

Tôi luôn có ác cảm với các con trỏ, rằng tôi đã viết nó để tôi có thể hiểu rõ hơn về nó. Nó hoàn toàn dựa trên câu trả lời của AA.SC (cảm ơn bạn bằng cách này), chỉ cần đặt theo cách mà tôi nghĩ. Nếu điều này sống với những gì người khác nghĩ, thì tuyệt vời. Lưu ý, sau đó tôi đã không đưa nó trở lại chế độ Khôi phục hoàn toàn.

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 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.