SQL Serverデータベース内の未使用のファイルグループ/ファイルをいくつか削除したかったのですが、SQL Serverがファイルグループ/ファイルがまだ使用中であると考えているために行き詰まっていました。
背景:
次のように、未使用のファイルグループのdmビューを照会しました。
SELECT
*
FROM sys.filegroups fg
LEFT OUTER JOIN
sysfilegroups sfg
ON fg.name = sfg.groupname
LEFT OUTER JOIN
sysfiles f
ON sfg.groupid = f.groupid
LEFT OUTER JOIN
sys.indexes i
ON fg.data_space_id = i.data_space_id
WHERE i.object_id IS NULL
これにより、データベースから削除しようとしたファイルグループ/ファイルのリストが表示されました。しかし、それらのいくつかは削除できませんでした。エラーメッセージの例:
The filegroup 'FG_XXXX' cannot be removed because it is not empty.
sys.data_spaces
およびsys.indexes
を介してこれらのファイルグループのテーブル/インデックスへの接続を取得できませんでした:
SELECT * FROM sys.data_spaces ds
INNER JOIN sys.indexes i
ON ds.data_space_id = i.data_space_id
WHERE ds.name = 'FG_XXXX'
一部のパーティション構成で参照されているファイルグループは削除できないことを認識しています。
しかし、これは理由ではありません。データベース内のすべてのパーティションスキーマ/関数を削除したためです。
ファイルグループを削除するために私ができることのヒントはありますか?
一部のLOBデータ(text/image/varchar(max)/ nvarchar(max))がファイルグループに残っている場合があります。私はこれに少し前から簡単に追いついた。別のファイルグループ/パーティションでテーブル/インデックスを再構築するしない LOBデータを移動します。
SELECT
au.*,
ds.name AS [data_space_name],
ds.type AS [data_space_type],
p.rows,
o.name AS [object_name]
FROM sys.allocation_units au
INNER JOIN sys.data_spaces ds
ON au.data_space_id = ds.data_space_id
INNER JOIN sys.partitions p
ON au.container_id = p.partition_id
INNER JOIN sys.objects o
ON p.object_id = o.object_id
WHERE au.type_desc = 'LOB_DATA'
それが実際に起こっていることである場合、LOBデータを移動する最も簡単な方法は、テーブルを再作成することです。 bcp out/inを使用するか、新しいテーブルに直接挿入して後から名前を変更することにより(または、データを移動するための他の望ましい方法で)、データを移動できます。新しいテーブルを作成するときは、行データとテキストデータに正しいファイルグループを指定してください。
Sys.indexesの代わりにsys.allocation_unitsを使用してみてください。 BOLは内部使用のみを目的としているため、長期的なコードは記述しませんが、この目的のために問題はありません。各アロケーションユニットの最初のIAMページを指します。私はそれがあなたがやろうとしていることに対してよりうまく機能すると信じています。
SELECT *
FROM sys.filegroups fg
LEFT OUTER JOIN sysfilegroups sfg
ON fg.name = sfg.groupname
LEFT OUTER JOIN sysfiles f
ON sfg.groupid = f.groupid
LEFT OUTER JOIN sys.allocation_units i
ON fg.data_space_id = i.data_space_id
WHERE i.data_space_id IS NULL
また、@ RobertGannonが言ったように、データベースの名前を右クリックして、タスク、縮小、ファイルに移動できます。
次に、「データを同じファイルグループ内の他のファイルに移行してファイルを空にする」を選択して、特定のファイルからすべてのデータを取得できます。これはファイルグループ自体を取り除くのに役立ちませんが、単一のファイルに圧縮することができます。
同じ問題があったので、この修正の簡単な解決策を実際に見つけました。
ファイルグループ[fg_LMeterDetail_13]
を削除しようとしましたが、「空ではないため削除できません」というエラーが表示されました。このファイルグループの唯一の罪は、パーティション構成に関連付けられていました。このファイルグループにはデータがありませんでした。
そのため、NEXT USED
と反対のものがないことを確認した後、実験を行ったところ、別のNEXT USED
を発行できることを発見しましたが、前のファイルグループを指すようにしました。
ALTER PARTITION SCHEME ps_LMeterDetail
NEXT USED [fg_LMeterDetail_12]
その後、REMOVE FILEGROUP
を発行して、パーティションスキームから自動的に削除することができました
ALTER DATABASE [WACOE]
REMOVE FILEGROUP [fg_LMeterDetail_13]
出来上がり!出来た!
どういたしまして。
パーティションスキーマを削除してからパーティション関数を削除した後、ファイルグループを削除することができました。
DROP PARTITION SCHEME <<PartitionSchemeName>>;
DROP PARTITION FUNCTION <<PartitoinFunctionName>>;
ALTER DATABASE DBNAME
REMOVE FILEGROUP PartitionFG
エラーは一般的で誤解を招くものです。削除しようとしているFileGroupにPARTITION SCHEMEが割り当てられている場合にも、このエラーが発生します。
ファイルグループを使用しているパーティション構成を削除すると、問題が解決しました。
ファイルを縮小し、それらがデフォルトのファイルグループではないことを確認します。縮小すると、EMPTYFILEを使用してファイルが空であることを確認できます。 SQL Serverでは、デフォルトのファイルグループを削除できません。