私は、ライブの30GBコピーであるSQL Server 2005開発データベースを持っています。 devで不要なデータをいくつか削除しました。これにより、使用されるデータファイル領域が20GBに下がります。したがって、約33%が未使用です。
スペースを再利用する必要があります。これにより、サーバーに2番目の開発用DBを配置できます(削減バージョンに基づく)。ただし、スペースを取り戻すことはできません。次のようにしました。
ファイルの初期サイズSMS2_Data
は30 GBです。
DBCC SHRINKFILE (N'SMS2_Data' , 0, TRUNCATEONLY)
に続く
DBCC SHRINKFILE (N'SMS2_Data' , 19500)
喜びがない。バックアップを作成し、初期サイズの小さい新しいDBを作成してから復元しようとしましたが、初期サイズが上書きされて喜びません。また試しました:
ALTER DATABASE SMS2HazSub MODIFY FILE (NAME = 'SMS2_Data', SIZE = 20000)
これは誤り、言った:
MODIFY FILEが失敗しました。指定されたサイズは現在のサイズよりも小さいです。
20800を試してから29000(29GB)まで上がり続けましたが、それでも変更できません。
圧縮を行った後、リカバリモードをFULL
からSIMPLE
に変更し、再び元に戻しました。喜びがない。
いくつかのTEXT
フィールドと関係があると思いました。システム全体で約6つあります。テストとして、すべてを削除してからファイルを縮小しましたが、変更はありませんでした。
残っている唯一のオプションは、データを別のDBに再インポートすることです。ライブDBで実行する必要があるため、リスクが高すぎるため、これは実用的ではありません。ライブDBのコピーを半定期的に取得し、dev/testを上書きします。 500テーブルのようなものがあります。新しいDBにデータをエクスポートするリスクのない方法を教えてください。
データを別のファイルに移動しようとすると、データの5%を除くすべてがコピーされました。これが、すべてのテキスト列を削除しようとした理由です。
サーバーは互換モード90ですが、SP2です。すべてのテーブルのインデックスの再作成、データベースのバックアップ、ファイルの圧縮、データベースの圧縮を3回実行しました。まだ喜びはありません。
EXECUTE sp_spaceused
戻り値:
database_name database_size unallocated space
SMS2Tests 31453.94 MB 13903.16 MB
reserved data index_size unused
16545568 KB 10602264 KB 4254360 KB 1688944 KB
一部の人々がすでに述べたように、新しいデータベースを作成し、古いデータベースから「コピー」することができます。これはあなたにとって最良の選択肢でしょう。しかし、私はあなたがかなり定期的にそれをしたいことに気づきました。したがって、最適なオプションは Redgate Data Compare および Redgate Compare です。どちらも Redgate SqlToolbelt パッケージの一部です。
だからあなたがすること:
データ比較の優れている点は、30 GBのデータをコピーした後(一部のテーブルからのみ開始できます)、しばらくすると、30 GBのデータ全体ではなく、一部の変更のみを「再比較」する必要があることです。つまり、通常の方法でコピーするよりも、両方のデータベースへの影響がはるかに少なくなります。
ここにいくつかの可能性があります。
まず、SQL 2005 SP3以降を使用していますか?以前のバージョンでSHRINKFILEの問題が報告されている人もいます( http://www.sqlservercentral.com/Forums/Topic981292-146-6.aspx#bm985164 を参照)
次に、データベースがモード80互換ではなくモード90互換に設定されていることを確認できますか?これは明らかにSQL 2000の問題でしたが、SQL 2005で制限が解除されました。データベースが引き続きモード80互換に設定されている場合、これはまだ問題である可能性があります。
3番目に、これはLOBデータ(text、ntext、varchar(max))の問題である可能性があります。 Paul Randallのすばらしい 記事はこちら を参照してください
SHRINKingが実際に行うことを理解していて、パフォーマンスに悪影響を与える可能性があると想定しています。
私は通常、フルリインデックス(解放されたばかりの領域の一部を再利用します)を使用して縮小を追跡することをお勧めしますが、その時点に到達することさえできないようです。
アクティビティモニターで縮小SPIDを確認すると、何かが実行されているように見えますか? (IOカウンターとCPUカウンターは変化します)またはブロックされていますか?私が考えることができる他の唯一のことは、データベース上で他の活動があり、縮小を妨げている場合です。その時点で他のアクティブなspidがデータベースを使用していないことを確認してください。
このプロセス中に単純復旧モードに切り替えることも、ログが大きくなりすぎないようにするための良いアイデアです。
SHRINKDATABASE
は、データベースを(最大でも)MinSizeに縮小するだけなので、役に立ちません。
デフォルトを使用してSSMS UI経由でファイルを圧縮しようとすると、 'DBCC SHRINKFILE(N'MyDB'、0、TRUNCATEONLY) 'が使用されます。このコマンドは、ファイルを(最大でも)最後に割り当てられたエクステントにのみ縮小します。
ファイルをMinSize未満に縮小する場合は、_DBCC SHRINKFILE
_のパラメーターを0からMB単位でファイルを縮小しようとするサイズに変更します。ゼロ以外の数値は、可能であればファイルをそのサイズに縮小するようにSHRINKFILEに指示します。したがって、データベースにスペースがある場合、DBCC SHRINKFILE('MyDB', 300, TRUNCATEONLY)
はファイルを300MBに縮小します。
これを実行すると、MinSizeを確認できます。
_DBCC TRACEON(3604)
go
DBCC PAGE('MyDB', 1, 0, 3) with tableresults
go
_
MB単位のMinSizeは次のように計算されます:(MinSize * 8)/ 1024
あなたが本当にこれをしたい場合:
DBCC SHRINKDATABASE (MyDatabase, TRUNCATEONLY);
たとえば、データベースに20003(mb)の実際のデータがある場合、 "SIZE = 20000"は小さすぎます。 21000または25000で試してみて、それが機能するかどうかを確認します。 (そして、1 GB = 1024 MBを覚えておいてください。)
試す
DBCC SHRINKDATABASE (N'SMS2_Data' , 0)
ここにあるSQL 2005データベースでこれを使用し、データファイルに割り当てられたスペースは10.2 GBから3 GBになりました。
Fyi、これは長いプロセスであり、私のデータベースでは19分強かかりました。
論理名SMS2_Dataの単一のデータベースファイルがあると想定しています。また、データベースには1つ以上のトランザクションログファイルがあります。
データベースの現在のコピーでは修正できない課題があります。あなたが述べる重要な情報は、「データベースファイルの元のサイズは30 GB」です。残念ながら、このファイルは元のサイズよりも小さくすることはできません。
すでに経験したように、SHRINKDBとSHRINKFILEは必要なものを提供しません。これらのコマンドは、元のサイズルールよりも小さくできないというルールに従います。そのため、データベースを元のサイズに縮小することのみが可能で、それより小さくすることはできません。
データベースのバックアップと既存の小規模なデータベースへの復元も機能しません。データベースの復元を実行すると、データベースファイルは、バックアップ時のファイルサイズに復元されます。また、復旧モデル(シンプル、フルなど)はこの問題とは無関係です。
そして、最後の悪い知らせです。他のより小さなデータベースファイルをデータベースに追加し、すべてのデータを30 GBファイルから転送してから削除することを検討する場合があります。残念ながら、データベースから初期ファイルを削除できないため、これも機能しません。
したがって、最善の解決策は、データを別のデータベースにコピーすることです。ここにはいくつかのオプションがあり、おそらくすでに知っているでしょう。最初のステップは、データサイズよりも小さいサイズの新しいデータベースを作成することです。次に、データベースのサイズを必要なサイズに拡張できます。
あるデータベースから別のデータベースにデータを転送する方法として、SSISを検討できます。あなたはあなたを助けるデータベースコピータスクを見つけるでしょう。次の手順を使用できます。
SSIS データベース転送タスク に関する追加情報を参照してください。
データベースの一部の未使用スペースは正常です。
大きなレコード(たとえば、長い文字列)が多数ある場合は、データページに未使用の領域が多く存在する可能性があります(通常、1つのレコードがページ間で分割されていないため)。
もう1つはFILL FACTORです。最初に、後続の挿入でページ分割(コストのかかる操作)を回避するために、クラスター化インデックスが100%フルで作成されるわけではありません。
データベースから大量のデータが削除された場合、これらのデータによって以前に占有されていたスペースは自動的に再利用されず、テーブルに割り当てられたままになります。
データベース内のすべてのテーブルでDBCC DBREINDEX (table_name, '', 100)
を呼び出してみてください。FILLFACTORが100%のすべてのインデックスが再構築されるため、データはできるだけコンパクトに配置されます。次に、データベースの圧縮を再試行してください。
SQL Serverデータベースの圧縮が面倒な場合があることを発見しました。歌と踊りをしなければならないような気がします。
これは私が通常経験するプロセスです:
バックアップ縮小データベースバックアップ縮小ログとデータベースファイルを個別に。最終的に縮小するまでバックアップを繰り返します。
私はそれが最終的に機能するために、このプロセスを数回から最大3回行う必要がありました。データベースのサイズは68 GBを超えており、98%の未使用領域がありました。この歌と踊りのルーチンを何度か試しましたが、最終的に1GB未満に縮小しました。
最初にmdfファイルの初期サイズを29 000 MBに減らし、次に28、000に近づけてヒットを検出しようとしました。
データの30%を削除することにより、データベースファイルサイズを30%削減することを期待するのは不合理です。
データベースの未使用領域の量を見積もることができます
execute sp_spaceused
データベースのコンテキスト内(yourdatabaename;を使用)
その実行結果を投稿できますか?
更新:
関連する質問を投稿しました: