ファイルが関連付けられていないファイルグループは削除できません


8

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て試してみました。それは私には本当に意味がありませんが、私はそれを修正として説明する解決策を読みます。とにかく効果がなかった。


サーバー障害に関するこの質問を読んで、次のことを試しました。

  • すべての統計を更新
  • インデックスに関連しないすべての統計を削除します

しかし、これは効果がありませんでした。ファイルが関連付けられていないファイルグループがまだあり、ファイルグループを削除できません。これは一部のデータベースで発生し、他のデータベースでは発生しない(同じ構造を持つ)ため、完全に困惑します。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つのデータベースのファイルグループとファイルのリストを次に示します。

  1. CCC_GENTE

+-----------------+------------+
| 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番目のデータベースもありますが、簡潔にするために省略しています。


1
SQL2017については触れていませんが、バグは2017年にも残っているのでしょうか?support.microsoft.com/en-us/help/3132058/...
SqlWorldWide

@SqlWorldWide:リンクをありがとう。ただし、フルテキストインデックスはなく、パーティション関数とスキーマは自分で削除しました。したがって、そのリンクは私の問題には当てはまらないと思います。
Martin Guth、2018

5042エラー全体を印刷できますか。状態は問題の内容を示しています。
Sean Gallardy-退職したユーザー

@ SeanGallardy-Microsoft:メッセージ5042、レベル16、ステータス8、行1ファイルグループ 'FG_AUDIT'は空ではないため削除できません。
マーティンガス2018

ありがとう:)状態8は、ファイルグループがオブジェクトによって使用されていることを意味します。これはサポート記事とは異なります(状態12で、これはfgがパーティション構成で使用されることを意味します)。奇妙なことに、ファイルグループにはファイルがありません。問題が発生してから複数のログバックアップ(フル/バルクの場合)が取られていると思いますか?
Sean Gallardy-退職したユーザー

回答:


4

データベース内のファイルグループの再確認

次のコマンドを発行して、ファイルグループに添付ファイルが残っていないことを確認します。

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

ファイルグループ「xyz」がデフォルトです

次のようなファイルグループの論理ファイルを削除しようとしたときにエラーメッセージが表示された場合:

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

ファイルグループ 'xyz'は読み取り専用です

ただし、エラーメッセージが次の場合:

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)が本当にない場合、トランザクションログバックアップを実行すると、トランザクションが解放され、ファイルグループの削除を妨げる可能性があります。

911にダイヤル

他のすべてが失敗した場合は、Microsoftとの電話をかけることを検討してください。


メタデータの不一致

さらなる調査の後に追加

明らかに、データベース内のメタデータがオブジェクトの実際の場所を反映していない場合があります。

参考:
- FIX:メタデータの矛盾エラーは、テーブルのパーティションを切り替えると、ファイルとファイルグループに対応するドロップした後、(マイクロソフトのサポート)
- FIX:あなたはSQL Serverで落としたり、削除ファイルグループまたはパーティションスキームと機能するときにエラーが発生した(マイクロソフトのサポートを)

これら2つのケースは、SQL Server 2014 SP1の累積的な更新3および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:パーティションとメタデータの不整合の問題(ブログ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)


sp_helpfilegroup:FG_AUDIT groupid 2 filecount 0ファイルなし
Martin Guth

データベースは単純な復旧モデルであり、現在(テストサーバー全体で)開いているトランザクションはありません
Martin Guth

フィードバックをお寄せいただきありがとうございます。この情報を質問に追加できますか?エラーメッセージ(...CCC_APPLICATION_new...;一時ファイルグループですか?)をもう少し考えて、私の環境で再現してみます。
John aka hot2use

1
CCC_APPLICATION_newは一時ファイルグループではありません...内容が移動されたファイルグループです...名前を「CCC_APPLICATION」に変更する必要があります...ただし、これは、CCC_APPLICATIONという名前のファイルが関連付けられていないファイルグループが削除されたか、名前が変更されました(ただし、ぶらぶらしたくありません)
Martin Guth

1
明確化のために:私は2つの異なるデータベースで問題を抱えています... 1つは古いファイルグループCCC_APPLICATIONと新しいファイルグループCCC_APPLICATION_new、もう1つは古いファイルグループFG_AUDITと新しいファイルグループCCC_AUDIT
Martin Guth

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を介してデータをコピーし、古いテーブルを削除し、新しいテーブルの名前を変更します(もちろん、プロセス全体に外部キーがある場合は、外部キーを処理します)。 )


私は何年もの間この答えを探していました。どうもありがとう!
Christian4145
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.