2013-11-26 59 views
13

私はデータベースを持っています。21 Gb;それらの20 Gbはファイル(FileStream)であり、テーブルからすべてのファイルを削除していますが、バックアップを作成するとバックアップファイルはまだ21 GBです。DBCC SHRINKFILEの進捗状況

この問題を解決するために、私は「未使用スペースを解放する」という理想になりました。

だから私は、次のように私のデータベースを縮小にしようとしている:私は、

USE Db; 
GO 
-- Truncate the log by changing the database recovery model to SIMPLE. 
ALTER DATABASE Db 
SET RECOVERY SIMPLE; 
GO 
-- Shrink the truncated log file to 1 MB. 
DBCC SHRINKFILE (Db, 100); 
GO 
-- Reset the database recovery model. 
ALTER DATABASE Db 
SET RECOVERY FULL; 
GO 

SELECT file_id, name 
FROM sys.database_files; 
GO 
DBCC SHRINKFILE (1, TRUNCATEONLY); 

私はXX分後にデータベースのバックアップを作成する場合は、バックアップファイルのサイズがこのように1 GBです未使用スペースが正常にクリーニングされたことがわかります。つまり、上記のSqlコードが正しく動作しています(データベースのXX分後には、schrunk)。

SELECT percent_complete, start_time, status, command, estimated_completion_time, cpu_time, total_elapsed_time 
FROM sys.dm_exec_requests 

は私がSHRINKFILEに関する情報を見つけることができません。


私はこのクエリ(縮小操作)するまで待つ必要がある問題は、私は、次のやろうとしているので、終了します上記のクエリの結果のコマンド。

enter image description here


私が何か間違ったことをしましたか?なぜ私はDBの縮小操作の進捗状況を見ることができないのですか?

そして、私のメインのquesitonは次のとおりです。SHRINKFILEが完了するまで、どのように私は待つことができますか? たとえば、C#コードクエリから送信できますが、このクエリの結果では、SHRINKFILE操作が完了したかどうかの情報を取得しますか?

+3

これは両方ともデータベースを断片化し、ログチェーンを破ることを認識していますか?これは、1)データベースの縮小を決して自動化しないでください。2)次回の完全バックアップが完了するまでデータベースの復旧機能が危険にさらされているため、自動化する必要はありません。例外的に手動でこれを行うだけで、完了するまで個人的に監視する必要があります。それ以外の場合、問題のホストを招待しています。そのうちのいくつかは悲惨です。 – RBarryYoung

+0

私はすべてに同意します。そのため、データベースを変更している間にすべてのデータをブロックする必要があるのはなぜですか?たとえば、削除エントリのバックアップを追加するなどです。問題は、私たちの顧客の要求です。 –

+0

私にとっては、このプロセスが完了し、進捗バーではないことを知るだけで十分です。ShrinkFile操作がSQL文で終了したとき(プロセスSPIDがもう利用できなくなったためにC#からプールすることもできます) –

答えて

16

DBCC SHRINKFILEの進捗状況を測定する際の問題点は、ファイルを縮小するためにどのくらいの作業を行う必要があるかをエンジンが一貫した方法で知ることができないことです。これを理解するには、DBCC SHRINKFILEの仕組みを知ることです。基本的に、プロセスは次のとおりです。

  • あなたが特定のポイント(ダウン10ギガバイトから言う5ギガバイト、 )にファイルを縮小したい宣言する。
  • エンジンは、ファイルの末尾からファイルの先頭付近の次の開いた場所にページの移動を開始します。

Shrink File Movement

  • エンジンは、それがファイルサイズを小さくするか、できることをあなたの宣言のポイントの下に十分なページを移動します)AまでいっているB)すべての空スペースがのバックエンドであることファイル。

SQL Serverは、どのくらいの作業を行う必要があるのか​​わからないのはなぜですか?あなたの空き領域がどのように断片化しているのか分からないからです。物事がかなりよく圧縮され、ファイルの先頭近くにある場合、縮小ファイルはすばやく表示されます。そうでない場合は、時間がかかることがあります。良いニュースは、ページがファイル内で移動されると移動されることです。縮小ファイルを取り消しても、この作業は元に戻す/ロールバックしないので、しばらくの間シュリンクファイルを実行してから、完了する前に圧縮ファイルを削除すると、そのページ移動はそのまま残ります。つまり、縮小ファイルをに再起動することができます。これは、ファイル内に新しいページの作成を禁止したままの状態で、ほぼになります。

+0

ありがとうございます。これはあなたの言うことには当てはまりますが、シュリンク操作が実行されていることをどのように検出できますか?私はそれが終わるまでそれをプールすることができます。 –

+1

sp_who2の下に表示されます。ここで、commandはDbccSpaceReclaimです。[sp_whoisactive](http://sqlblog.com/files/default.aspx)を使用しています。 –

+0

私はDbCCSpaceReclaimを見ることができませんが、私はAWAITINGCOMMANDと呼ばれる新しいものを見ることができます。これは縮小後に新しい直接的に来ました。私はSPIDに印をつけて、これをチェックします。終わる時。 –

0

私はこの問題を別の方法で解決しましたが、この解決策ではスレッドを待つ必要はありません。

この方法では、テーブルインデックスは再編成されませんが、ストリーミングファイルはハードディスクから削除され、空き領域がOSに再利用されます。

以下のコードを知りたい人は、同じスレッドで動作します。したがって、これはShrinkプロセスの進捗状況を示すものではありませんが、アプリケーションスレッドでのみ実行します。

var db = EFDbContext; 
    try 
    { 
     db.ExecuteSqlCommand(@"USE [master] 

            ALTER DATABASE DatabaseName 
            SET RECOVERY SIMPLE"); 

     db.ExecuteSqlCommand(@"USE [master] 

            EXEC sp_filestream_force_garbage_collection 'DatabaseName'"); 

     db.ExecuteSqlCommand(@"USE [master] 

            EXEC sp_filestream_force_garbage_collection 'DatabaseName'"); 
     } 

    } 
    catch (Exception e) 
    { 
     throw new DatabaseException(e.Message, e); 
    } 
    finally 
    { 
      db.ExecuteSqlCommand(@"USE [master] 
            ALTER DATABASE DatabaseName 
            SET RECOVERY FULL"); 
    } 
関連する問題