79

次の情報を含むデータベース[MyDB]があります
。SQLServer2008MDF
サイズ:30 GB
LDFサイズ:67 GB

ログファイルをできるだけ縮小したかったので、これを行う方法を見つけるために探求を始めました。警告:私はDBAではなく(またはDBAに近づいていません)、この探求を通して感じて進歩してきました。

まず、SSMS、DBプロパティ、ファイルに移動し、初期サイズ(MB)の値を10に編集しました。これにより、ログファイルが62 GBに減少しました(入力した10 MBとは異なります)。そこで、SQLプロファイラーをアタッチして、DBCCSHRINKFILEが呼び出されていることを確認しました。次に、そのコマンドをクエリエディタに入力しました。結果は次のとおりです。

DBCC SHRINKFILE (N'My DB_Log' , 10)

そして、出力は次のとおりです。

Cannot shrink log file 2 (My DB_Log) because the logical log file located at the end of the file is in use.
DbId   FileId      CurrentSize MinimumSize UsedPages   EstimatedPages
------ ----------- ----------- ----------- ----------- --------------
8      2           8044104     12800       8044104     12800

(1 row(s) affected)

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

それから私はそれについていくつかの調査をし、これを見つけました:

http://support.microsoft.com/kb/907511

これは、仮想ログファイルが解放され、シュリンクファイルがその仕事を実行できるように、シュリンクファイルの前にログファイルをバックアップする必要があることを示しています-それが何を意味するのかわかりません...私はここで言い換えています:)

したがって、ログファイルをバックアップしてからDBCC SHRINKFILEを実行しようと考えました(前のDBCC SHRINKFILEコマンドの出力で識別されたMinimumSizeであったため、新しいログファイルサイズを12800に変更しました)

BACKUP LOG [My DB] TO DISK = 'D:\SQLBackup\20110824-MyDB-Log.bak'
GO
DBCC SHRINKFILE (N'My DB_Log' , 12800)
GO

結果は最初の周回と同じでした。ログファイルは62GBまでしか取得できません。

何が間違っているのか、次に何を試すべきかわかりません。

4

9 に答える 9

139

さて、これはトランザクションファイルの物理的なサイズを減らすための解決策ですが、リカバリモードをシンプルに変更することはありません。

データベース内で、次のクエリを使用してログファイルのfile_idを見つけます。

SELECT * FROM sys.database_files;

私の例では、ログファイルはfile_id 2です。ここで、使用中の仮想ログを見つけて、次のコマンドでこれを実行します。

DBCC LOGINFO;

ここでは、ステータスが2(使用中)または0(無料)のどちらであるかを確認することで、仮想ログが使用中であるかどうかを確認できます。ファイルを縮小する場合、空の仮想ログは、ファイルの最後から最初に使用されたステータスに達するまで物理的に削除されます。これが、トランザクションログファイルを縮小すると途中で縮小されることがありますが、すべての空き仮想ログが削除されるわけではない理由です。

0の後にステータス2が発生することに気付いた場合、これは縮小がファイルを完全に縮小するのをブロックしています。これを回避するには、別のトランザクションログのバックアップを実行し、すぐにこれらのコマンドを実行して、上記のfile_idと、ログファイルを縮小するサイズを指定します。

-- DBCC SHRINKFILE (file_id, LogSize_MB)
DBCC SHRINKFILE (2, 100);
DBCC LOGINFO;

これにより、仮想ログファイルの割り当てが表示され、多少減少していることに気付くと思います。仮想ログファイルは常に順番に割り当てられるとは限らないため、トランザクションログを数回バックアップして、この最後のクエリを再度実行する必要がある場合があります。しかし、私は通常、1つか2つのバックアップ内でそれを縮小することができます。

于 2014-02-17T03:38:02.710 に答える
44

すでに実行した手順に加えて、ログを縮小する前に、リカバリモードをシンプルに設定する必要があります。

これは、本番システムに推奨される方法ではありません...以前のバックアップ/ログファイルから特定の時点に回復する能力が失われます。

例と説明については、このDBCC SHRINKFILE(Transact-SQL) msdnページの例Bを参照してください。

于 2011-08-25T16:09:29.337 に答える
12

これを試して

ALTER DATABASE XXXX  SET RECOVERY SIMPLE

use XXXX

declare @log_File_Name varchar(200) 

select @log_File_Name  = name from sysfiles where filename like '%LDF'

declare @i int = FILE_IDEX ( @log_File_Name)

dbcc shrinkfile ( @i , 50) 
于 2013-07-29T14:25:35.913 に答える
12

このスクリプトはSQLServer2008R2で使用しています。

USE [db_name]

ALTER DATABASE [db_name] SET RECOVERY SIMPLE WITH NO_WAIT

DBCC SHRINKFILE([log_file_name]/log_file_number, wanted_size)

ALTER DATABASE [db_name] SET RECOVERY FULL WITH NO_WAIT
于 2014-04-08T09:36:23.620 に答える
4

Paul Randalは、彼のブログでこの問題について優れた議論をしています:http ://www.sqlskills.com/blogs/paul/post/backup-log-with-no_log-use-abuse-and-undocumented-trace-flags-to -stop-it.aspx

于 2012-08-21T14:12:15.567 に答える
3

私は多くの方法を試しましたが、これはうまくいきます。

サンプルコードはDBCCSHRINKFILEで利用できます

USE DBName;  
GO  
-- Truncate the log by changing the database recovery model to SIMPLE.  
ALTER DATABASE DBName  
SET RECOVERY SIMPLE;  
GO  
-- Shrink the truncated log file to 1 MB.  
DBCC SHRINKFILE (DBName_log, 1);  --File name SELECT * FROM sys.database_files; query to get the file name
GO  
-- Reset the database recovery model.  
ALTER DATABASE DBName  
SET RECOVERY FULL;  
GO
于 2017-07-19T06:30:52.473 に答える
1

完全バックアップとトランザクションバックアップを作成することで、この問題を解決しました。バックアッププロセスが完了していない場合があります。これが、.ldfファイルが縮小されない理由の1つです。これを試して。それは私のために働いた。

于 2020-11-13T08:40:21.160 に答える
0

トランザクションの多いデータベースの1つは、ログテーブルに毎日数十万のレコードを増やしています。毎日数百GB増加する複数のログファイルがあります。

30分ごとに差分バックアップをとるスケジュールされたジョブがあります。毎日早朝に実行されるハウスキーピングの別のスケジュールされた仕事があります。

RECOVERYをSIMPLEに設定した後、ハウスキーピング中にSHRINKFILEを実行します。以前のバックアップ/ログファイルから特定の時点に回復する能力が失われるという問題を克服するために、プロセスの最初と最後に完全バックアップを取ります。データベースのフラグを使用して、ハウスキーピングジョブが完了するまで差分バックアップが試行されないようにします。簡単な概要は次のとおりです-ハウスキーピングの仕事:

  1. ステータスを「ハウスキーピング進行中」に設定します
  2. データベースをシングルユーザーモードに設定する
  3. データベースの完全バックアップを取ります
  4. 古いさまざまなテーブルからレコードを削除します
  5. データベースの回復モードをSIMPLEに設定します
  6. ログファイルを繰り返し処理し、それぞれを縮小します
  7. データベースのRECOVERYモードをFULLに設定します
  8. データベースの完全バックアップを取ります
  9. データベースをマルチユーザーモードに設定します
  10. ステータスを「ハウスキーピング完了」に設定します

差分バックアップジョブ:

  1. ステータスが「ハウスキーピング完了」の場合にのみ続行します
  2. 差分バックアップを取る

完了するまでにしばらく時間がかかりますが、通常のビジネスが午前中に開始される前に、データベースが整頓されて新鮮になります。それは私たちのためにうまく働いています。

于 2021-06-20T07:07:05.300 に答える
-1

@user2630576と@Ed.Sに感謝します。

以下は御馳走を働いた:

BACKUP LOG [database] TO DISK = 'D:\database.bak'
GO

ALTER DATABASE [database] SET RECOVERY SIMPLE

use [database]

declare @log_File_Name varchar(200)

select @log_File_Name = name from sysfiles where filename like '%LDF'

declare @i int = FILE_IDEX ( @log_File_Name)

dbcc shrinkfile ( @i , 50)

ALTER DATABASE [database] SET RECOVERY FULL
于 2014-01-21T00:02:24.867 に答える