SQL Server 2017 CU3で奇妙なエラーメッセージが発生します。データベースを移行し、ファイルグループを再編成しています。 「再編成」とは、 ストアドプロシージャ を使用して、オブジェクトの新しいファイルグループにパーティション関数とパーティション構成を作成し、パーティション分割中にインデックスを再構築してから、パーティション分割を削除することを意味します。
最後に、いくつかの空のファイルグループを取得しました。それらのファイルは削除されます。また、ファイルグループ自体も削除されます。これはほとんどの場合うまくいきます。ただし、2つのデータベースの場合、ファイルを削除しました...関連付けられているファイルがないファイルグループがありますが、
ALTER DATABASE REMOVE FILEGROUP
エラー5042をスローします。
ファイルグループ 'xyz'は空ではないため削除できません。
空のファイルグループを削除するにはどうすればよいですか?
私はすでにいくつかの一般的な問題を読みましたが、それらは私のシステムにはありません:
チェック済み:
SELECT * FROM sys.partition_schemes;
SELECT * FROM sys.partition_functions;
0行...データベースにパーティションオブジェクトが残っていません
UPDATE STATISTICS
データベース内のすべてのオブジェクト
無効
ファイルグループのインデックスをチェックします。
SELECT * FROM sys.data_spaces ds
INNER JOIN sys.indexes i
ON ds.data_space_id = i.data_space_id
WHERE ds.name = 'xyz'
0行
ファイルグループ内のオブジェクトを確認します。
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'
AND ds.name ='xyz'
0行
DBCC SHRINKFILE
パラメータEMPTYFILE
を使用して、ファイルグループからファイルを削除する前に試してください。それは私には本当に意味がありませんが、私はそれを修正として説明する解決策を読みます。とにかく効果がなかった。
私はこれを読んでいくつかの希望を得ました question on server faultと以下を試しました:
しかし、これは効果がありませんでした。ファイルが関連付けられていないファイルグループがまだあり、ファイルグループを削除できません。これは一部のデータベースで発生し、他のデータベースでは発生しない(同じ構造を持つ)ため、完全に困惑します。 DBCC CHECK FILEGROUP
この空のファイルグループで、次のような一連のエラーメッセージが表示されます。
チェックされていないファイルグループ "CCC_APPLICATION_new"(ID 8)に存在するため、オブジェクト "STORY_TRANSLATIONSCCC"(ID 120387498)、インデックス "Ref90159CCC"(ID 2)の行セットID 72057594712162304を処理できません。
'STORY_TRANSLATIONSCCC'のDBCC結果。オブジェクト「STORY_TRANSLATIONSCCC」の0ページに0行あります。
これは正常ですか、それとも異常なことを示していますか?
この質問は重複している可能性がありますが、dba.stackexchangeに関する他の質問で私に役立つ解決策を見つけることができません。私が既に試したことをリストで見てください。これは 未使用のファイルグループを削除できない で説明されているソリューションと同じです。
詳細
エラーが発生する前に私が何をすべきかを理解するのに役立つかもしれません。新しいサーバーへの移行を計画しています。現在、これをテストインスタンスでテストしています。データベースは本番サーバーから復元され、復旧モデルはシンプルに切り替えられます。私の目標は、ファイルグループを再構築し、ファイルグループごとに1つのファイルを持つモデルから、ファイルグループごとに2つのファイルを持つモデルに移動することです。それを実現するために、それぞれ2つのファイルを持つ新しい空のファイルグループを作成し、データを移動します。残念ながら、ほとんどのオブジェクトにはLOBデータ(XMLおよびバイナリ)があります。そのため、パーティション化をヘルパーとして活用して、LOBデータも移動します。最後に、すべてのデータは新しいファイルグループにあり、古いファイルグループは空です。次に、すべてのファイルを削除し、それぞれのファイルグループも削除します。プライマリファイルグループはそのまま残り、別のファイルが追加されます。別の 私の質問 でサンプルスクリプトを見つけることができます。このプロセスは正常に機能しますが、2つのデータベースではファイルを削除できますが、ファイルグループは削除できません。驚いたことに、これらのデータベースの構造は、他のデータベースの構造と同じである必要があり、データの移動や古いファイルグループの削除のプロセスで問題が発生することはありませんでした。
問題が発生した2つのデータベースのファイルグループとファイルのリストを次に示します。
前
+-----------------+------------+
| Filegroup | Filename |
+-----------------+------------+
| CCC_APPLICATION | CCC_APP |
+-----------------+------------+
| CCC_ARCHIVE | CCC_ARCHIV |
+-----------------+------------+
| CCC_AXN | CCC_AXN |
+-----------------+------------+
| CCC_GDV | CCC_GDV |
+-----------------+------------+
| PRIMARY | CCC |
+-----------------+------------+
後
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| Filegroup name | Filegroup temporary name | Filename (logical) | Status |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_APPLICATION | - | CCC_APP | file removed, filegroup cannot be removed (error) |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_ARCHIVE | - | CCC_ARCHIV | file and filegroup removed |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_AXN | - | CCC_AXN | file and filegroup removed |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_GDV | - | CCC_GDV | file and filegroup removed |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| PRIMARY | - | CCC | file renamed to PRIMARY_1 |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| PRIMARY | - | PRIMARY_2 | new file added |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_APPLICATION | CCC_APPLICATION_new | CCC_APPLICATION_1 | new filegroup renamed at the end |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_APPLICATION | CCC_APPLICATION_new | CCC_APPLICATION_2 | new filegroup renamed at the end |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_ARCHIVE | CCC_ARCHIVE_new | CCC_ARCHIVE_1 | new filegroup renamed at the end |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_ARCHIVE | CCC_ARCHIVE_new | CCC_ARCHIVE_2 | new filegroup renamed at the end |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_AXN | CCC_AXN_new | CCC_AXN_1 | new filegroup renamed at the end |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_AXN | CCC_AXN_new | CCC_AXN_2 | new filegroup renamed at the end |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_GDV | CCC_GDV_new | CCC_GDV_1 | new filegroup renamed at the end |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
| CCC_GDV | CCC_GDV_new | CCC_GDV_2 | new filegroup renamed at the end |
+-----------------+--------------------------+--------------------+----------------------------------------------------+
少しお役に立てば幸いです。ファイルグループ名が異なる2番目のデータベースもありますが、簡潔にするために省略しています。
4か月後、Microsoftサポートは解決策を見つけました。確かに、この空のファイルグループを参照するテーブルがありました。
テーブルは、次のステートメントによって識別されました。
SELECT t.[name] FROM sys.tables t
inner join sys.filegroups f
on t.lob_data_space_id = f.data_space_id
where f.name = 'xyz'
データを新しいテーブルに移動し、問題のあるテーブルを削除した後、ファイルグループは正常に削除されました。データを移動するプロセスは、同じ構造とインデックスで新しいテーブルを作成し、SELECT INTOを介してデータをコピーし、古いテーブルを削除し、新しいテーブルの名前を変更します(もちろん、プロセス全体に外部キーがある場合は、外部キーを処理します)。 )
次のコマンドを発行して、ファイルグループに添付ファイルが残っていないことを確認します。
use [DB]
go
sp_helpfilegroup
これにより、ファイルグループのリストが生成されます。
groupname | groupid | filecount
-----------+---------+-----------
PRIMARY | 1 | 1
xyz | 2 | 1
...次に、リストされているファイルグループごとに実行します
use [DB]
go
sp_helpfilegroup @filegroupname='PRIMARY'
go
sp_helpfilegroup @filegroupname='xyz'
出力は次のようになります。
groupname | groupid | filecount
-----------+---------+------------
xyz | 2 | 1
.... 2番目の出力は次のようになります。
file_in_group | fileid | filename | size | maxsize | growth
------------------+--------+-----------------------------------+---------+-----------+---------
xyz_logical_name | 3 | X:\SQL\SQL_DATA\xyz_filegroup.ndf | 5120 KB | Unlimited | 1024 KB
ファイルグループの1つに関連付けられたファイルがまだある場合、ファイルグループの論理ファイルとファイルグループ自体を削除する完全なコマンドは次のようになります。
USE [DB]
GO
ALTER DATABASE [DB] REMOVE FILE [xyz_logical_name]
GO
ALTER DATABASE [DB] REMOVE FILEGROUP [xyz]
GO
次のようなファイルグループの論理ファイルを削除しようとしたときにエラーメッセージが表示された場合:
Msg 5031, Level 16, State 1, Line 88 Cannot remove the file 'xyz_logical_name' because it is the only file in the DEFAULT filegroup.
...次に、PRIMARY
ファイルグループをDEFAULT
ファイルグループとして設定する必要があります。
ALTER DATABASE [DB] MODIFY FILEGROUP [PRIMARY] DEFAULT
ただし、エラーメッセージが次の場合:
Msg 5055, Level 16, State 2, Line 88 Cannot add, remove, or modify file 'xyz_logical_name'. The file is read-only.
...次に、xyz
ファイルグループのREAD_ONLYプロパティを削除する必要があります。
ALTER DATABASE [DB] MODIFY FILEGROUP [xyz] READWRITE
これで、ファイルグループの論理ファイルとファイルグループ自体を削除できるようになります。
削除しようとしているファイルグループxyz
に関連付けられているファイル(logical_name/pyhsical_file_name)が実際にない場合、トランザクションログバックアップを実行するとトランザクションが解放され、ファイルグループの削除を妨げる可能性があります。
他のすべてが失敗した場合は、Microsoftとの電話をかけることを検討してください。
さらに調査した後に追加
明らかに、データベース内のメタデータがオブジェクトの実際の場所を反映していない場合があります。
参照:
- FIX:テーブルパーティションを切り替えて、対応するファイルとファイルグループを削除した後のメタデータの不整合エラー (Microsoftサポート)
- FIX:SQL Serverでファイルグループまたはパーティション構成と関数を削除または削除しようとするとエラーが発生します (Microsoftサポート)
これら2つのケースは、それぞれSQL Server 2014 SP1の累積的な更新およびSQL Server 2016の累積的な更新1で解決されているようです。それらはあなたの状況には当てはまりませんが、時にはメタデータが間違っている可能性があることを示しています。
ファイルグループの削除をブロックしていると思われるアイテムはインデックスです。これは、誤ったメタデータで保存されている可能性があります。
インデックスの再構築を検討してくださいRef90159CCC
エラーメッセージで参照されています。
Cannot process rowset ID 72057594712162304 of object "STORY_TRANSLATIONSCCC" (ID 120387498), index "Ref90159CCC" (ID 2), because it resides on filegroup "CCC_APPLICATION_new" (ID 8), which was not checked.
次の記事では、同様の状況について説明し、著者がどのようにして犯人を見つけて解決したかを示します。
参照:SQL Server:スイッチパーティションとメタデータの不整合の問題 (Blog dbi -services.com)
テーブル/インデックス/パーティション/その他の可能な限り多くの隠れ場所をチェックするために、このスクリプトを作りました。削除されたファイルグループファイルに関連している可能性があります。
DEFAULTRO
を、廃止されたファイルグループの名前に置き換えてください(例:CCC_APPLICATION
)
/* ==================================================================
Author......: hot2use
Date........: 16.02.2018
Version.....: 0.1
Server......: LOCALHOST (first created for)
Database....: StackExchange
Owner.......: -
Table.......: -
Type........: Script
Name........: ADMIN_Filegroup_Statement_All_Objects.sql
Description.: Checks all objects related to filegroups based on the
............ relationship between the data_space_id ID.
............
History.....: 0.1 h2u First created
............
............
================================================================== */
DECLARE @nvObsoleteFG AS NVARCHAR(50)
SET @nvObsoleteFG = N'DEFAULTRO'
SELECT -- DISTINCT use in conjunction with sys.allocation_units table and objects
'-->' AS DataSpaceNfo
,ds.name AS DataSpaceName
,ds.data_space_id AS DatSpacID_DataSpace
,'-->' AS FileGroupNfo
,f.name AS FileGrpName
,f.data_space_id AS DatSpacID_FileGrp
,f.[type] AS FileGrpType
,'-->' AS DataBaseFilesNfo
,df.data_space_id AS DatSpacID_DBFiles
,df.[type] AS DBFilesType
,df.name AS DBFilesName
,'-->' AS ObjectNfo
,o.[object_id] AS OjbID
,o.name AS ObjName4HeapsClusters
,o.type_desc AS ObjTypeDesc
,'-->' AS IndexNfo
,i.name AS ObjName4Indexes
,i.type_desc AS IndTypeDesc
,i.[object_id] AS IndObjID
,i.index_id AS IndIndID
,'-->' AS PartSchemaNfo
,ps.name AS PartSchemaName
,ps.data_space_id AS DatSpacID_PartSchema
-- ,au.type_desc AS AllocUnitTypeDesc
-- ,au.data_space_id AS DatSpacID_AllocUnit
FROM sys.data_spaces AS ds
FULL JOIN sys.filegroups AS f
ON ds.data_space_id = f.data_space_id
FULL JOIN sys.database_files AS df
ON f.data_space_id = df.data_space_id
FULL JOIN sys.indexes AS i
ON f.data_space_id = i.data_space_id
FULL JOIN sys.partition_schemes AS ps
ON f.data_space_id = ps.data_space_id
FULL JOIN sys.objects AS o
ON i.[object_id] = o.[object_id]
-- FULL JOIN sys.allocation_units AS au
-- ON au.data_space_id = f.data_space_id
-- If you omit the whole WHERE clause you get an overview of everything (incl. MS objects)
WHERE o.is_ms_shipped = 0
-- if you omit the lower AND you'll get all items related to all filegroups
AND (
df.data_space_id=(
SELECT data_space_id
FROM sys.filegroups
WHERE NAME = @nvObsoleteFG
)
OR f.data_space_id=(
SELECT data_space_id
FROM sys.filegroups
WHERE NAME = @nvObsoleteFG
)
OR df.data_space_id=(
SELECT data_space_id
FROM sys.filegroups
WHERE NAME = @nvObsoleteFG
)
OR ps.data_space_id=(
SELECT data_space_id
FROM sys.filegroups
WHERE NAME = @nvObsoleteFG
)
)
参照:マイパーソナルスクリプト
それを実行し、古いファイルグループを含むオブジェクトが表示されるかどうかを確認します。 data_space_id
という名前ではなく。結合は、「孤立した」参照をキャッチするために意図的にFULL
です。
または、次の小さなスクリプトを使用して、廃止されたファイルグループ内のアイテムをすばやく確認します。
SELECT o.[name]
,o.[type]
,i.[name]
,i.[index_id]
,f.[name]
FROM sys.indexes i
INNER JOIN sys.filegroups f
ON i.data_space_id = f.data_space_id
INNER JOIN sys.all_objects o
ON i.[object_id] = o.[object_id]
WHERE i.data_space_id = f.data_space_id
AND o.type = 'U' -- User Created Tables
参照:SQL SERVER –データベース内のすべてのファイルグループで作成されたすべてのオブジェクトを一覧表示 (SQLAuthority.com)