Dateigruppe kann nicht entfernt werden, wenn keine Dateien zugeordnet sind


8

Auf SQL Server 2017 CU3 treten einige seltsame Fehlermeldungen auf. Ich migriere Datenbanken und reorganisiere Dateigruppen. Mit "Reorganisieren" meine ich, dass ich eine gespeicherte Prozedur verwende, die eine Partitionsfunktion und ein Partitionsschema für die neue Dateigruppe für ein Objekt erstellt, die Indizes während der Partitionierung neu erstellt und dann die Partitionierung entfernt.

Am Ende habe ich einige leere Dateigruppen. Ihre Dateien werden entfernt . Auch die Dateigruppe selbst wird entfernt. Dies funktioniert in den meisten Fällen gut. Doch für zwei Datenbanken entfernte ich die Dateien ... hat eine Dateigruppe ohne Datei links assoziiert , aber

ALTER DATABASE REMOVE FILEGROUP

wirft einen Fehler 5042:

Die Dateigruppe 'xyz' kann nicht entfernt werden, da sie nicht leer ist.

Frage

Wie kann ich diese leere Dateigruppe loswerden ... was könnte das Problem sein?

Ich habe bereits einige häufig auftretende Probleme gelesen, die jedoch in meinem System nicht vorhanden sind:

  • Überprüft:

    SELECT * FROM sys.partition_schemes;
    SELECT * FROM sys.partition_functions;

    0 Zeilen ... keine Partitionierungsobjekte mehr in der Datenbank

  • UPDATE STATISTICS für alle Objekte in der Datenbank

    keine Wirkung

  • Überprüft die Dateigruppe auf Indizes:

    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 Zeilen

  • Überprüft, ob Objekte in der Dateigruppe vorhanden sind:

    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 Zeilen

Ich habe auch DBCC SHRINKFILEmit parameter EMPTYFILEversucht, bevor ich die Datei aus der Dateigruppe entfernt habe. Es macht für mich keinen Sinn, aber ich lese Lösungen, um das als Fix zu beschreiben. Hatte sowieso keine Wirkung.


Ich habe einige Hoffnung beim Lesen dieser Frage zum Serverfehler und habe Folgendes versucht:

  • Aktualisieren Sie alle Statistiken
  • Löschen Sie alle Statistiken, die sich nicht auf Indizes beziehen

Dies hatte jedoch keine Auswirkung. Ich habe immer noch eine Dateigruppe ohne zugeordnete Datei und die Dateigruppe kann nicht gelöscht werden. Ich bin total verwirrt, da dies in einigen Datenbanken und nicht in anderen (mit der gleichen Struktur) geschieht. Wenn ich DBCC CHECK FILEGROUPmit dieser leeren Dateigruppe arbeite, erhalte ich eine Reihe von Fehlermeldungen wie die folgenden:

Die Rowset-ID 72057594712162304 des Objekts "STORY_TRANSLATIONSCCC" (ID 120387498), Index "Ref90159CCC" (ID 2) kann nicht verarbeitet werden, da sie sich in der Dateigruppe "CCC_APPLICATION_new" (ID 8) befindet, die nicht überprüft wurde.

DBCC-Ergebnisse für 'STORY_TRANSLATIONSCCC'. Es gibt 0 Zeilen auf 0 Seiten für das Objekt "STORY_TRANSLATIONSCCC".

Ist das normal oder deutet es auf etwas Ungewöhnliches hin?

Diese Frage ist möglicherweise ein Duplikat, ich kann jedoch in anderen Fragen auf dba.stackexchange keine funktionierende Lösung für mich finden. Bitte schauen Sie sich die Liste an, was ich bereits ausprobiert habe. Dies ist identisch mit den unter Nicht verwendete Dateigruppen können nicht entfernt werden .

Mehr Details

Vielleicht hilft es zu verstehen, was ich mache, bevor der Fehler auftritt. Ich plane eine Migration auf einen neuen Server. Ich teste dies derzeit auf einer Testinstanz. Datenbanken werden vom Produktserver wiederhergestellt und das Wiederherstellungsmodell wird auf einfach umgestellt. Mein Ziel ist es, die Dateigruppen neu zu strukturieren und von einem Modell mit einer Datei pro Dateigruppe zu einem Modell mit zwei Dateien pro Dateigruppe zu wechseln. Um dies zu erreichen, erstelle ich neue leere Dateigruppen mit jeweils zwei Dateien und verschiebe die Daten. Leider haben die meisten Objekte LOB-Daten (XML und Binär) ... daher nutze ich die Partitionierung als Hilfsmittel, um auch die Lob-Daten zu verschieben. Am Ende befinden sich alle Daten in den neuen Dateigruppen und die alten Dateigruppen sind leer. Dann entferne ich alle Dateien und entferne auch die entsprechende Dateigruppe. Die primäre Dateigruppe bleibt erhalten und es wird nur eine weitere Datei hinzugefügt.Frage von mir . Dieser Vorgang funktioniert einwandfrei, aber in zwei Datenbanken können die Dateien gelöscht werden, die Dateigruppe jedoch nicht. Überraschenderweise sollte die Struktur dieser Datenbanken dieselbe sein wie die Struktur anderer Datenbanken, da beim Verschieben der Daten und Entfernen der alten Dateigruppen keine Probleme aufgetreten sind.

Hier ist eine Liste der Dateigruppen und Dateien der beiden Datenbanken, in denen das Problem auftritt:

  1. CCC_GENTE

Vor

+-----------------+------------+
| Filegroup       | Filename   |
+-----------------+------------+
| CCC_APPLICATION | CCC_APP    |
+-----------------+------------+
| CCC_ARCHIVE     | CCC_ARCHIV |
+-----------------+------------+
| CCC_AXN         | CCC_AXN    |
+-----------------+------------+
| CCC_GDV         | CCC_GDV    |
+-----------------+------------+
| PRIMARY         | CCC        |
+-----------------+------------+

nach

    +-----------------+--------------------------+--------------------+----------------------------------------------------+
| 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                   |
+-----------------+--------------------------+--------------------+----------------------------------------------------+

Ich hoffe das hilft ein bisschen. Es gibt auch eine zweite Datenbank, in der die Namen der Dateigruppen unterschiedlich sind, aber ich lasse dies der Kürze halber weg.


1
Ich weiß, dass SQL2017 nicht erwähnt wird, aber ich frage mich, ob der Fehler 2017 noch vorhanden ist. support.microsoft.com/en-us/help/3132058/…
SqlWorldWide

@ SQLWorldWide: Danke für den Link. Ich habe jedoch keine Volltextindizes und habe die Partitionsfunktionen und -schemata selbst entfernt. Daher denke ich, dass der Link nicht für mein Problem gilt.
Martin Guth

Können Sie den gesamten 5042-Fehler ausdrucken , gibt der Status das Problem an.
Sean Gallardy

@ SeanGallardy-Microsoft: Nachricht 5042, Ebene 16, Status 8, Zeile 1 Die Dateigruppe 'FG_AUDIT' kann nicht entfernt werden, da sie nicht leer ist.
Martin Guth

Danke :) Status 8 bedeutet, dass die Dateigruppe von einem Objekt verwendet wird. Dies unterscheidet sich vom Support-Artikel (das ist Status 12, was bedeutet, dass die fg von einem Partitionsschema verwendet wird). Was seltsam ist, dass Sie gesagt haben, die Dateigruppe enthält keine Dateien. Ich gehe davon aus, dass seit dem Auftreten des Problems mehrere Protokollsicherungen (wenn vollständig oder umfangreich) durchgeführt wurden.
Sean Gallardy

Antworten:


4

Überprüfen von Dateigruppen in der Datenbank

Stellen Sie sicher, dass an die Dateigruppe keine Dateien mehr angehängt sind, indem Sie den folgenden Befehl ausführen:

use [DB]
go
sp_helpfilegroup 

Dadurch wird eine Liste von Dateigruppen erstellt:

 groupname | groupid | filecount
-----------+---------+-----------
 PRIMARY   | 1       | 1
 xyz       | 2       | 1

... und dann für jede aufgelistete Dateigruppe ausführen

use [DB]
go
sp_helpfilegroup @filegroupname='PRIMARY'
go
sp_helpfilegroup @filegroupname='xyz'

Die Ausgabe könnte folgendermaßen aussehen:

 groupname | groupid | filecount
-----------+---------+------------
 xyz       | 2       | 1

.... und die zweite Ausgabe könnte sein:

  file_in_group    | fileid | filename                          | size    | maxsize   | growth  
 ------------------+--------+-----------------------------------+---------+-----------+---------
  xyz_logical_name | 3      | X:\SQL\SQL_DATA\xyz_filegroup.ndf | 5120 KB | Unlimited | 1024 KB  

Löschen der Dateigruppe

Wenn Sie noch eine Datei mit einer Ihrer Dateigruppen verknüpft haben, lautet der vollständige Befehl zum Löschen der logischen Datei der Dateigruppe und der Dateigruppe selbst:

USE [DB]
GO
ALTER DATABASE [DB] REMOVE FILE [xyz_logical_name]
GO
ALTER DATABASE [DB] REMOVE FILEGROUP [xyz]
GO

Dateigruppe 'xyz' ist Standard

Wenn beim Versuch, die logische Datei der Dateigruppe zu entfernen, eine Fehlermeldung angezeigt wird, die folgendermaßen aussieht:

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.

... dann müssen Sie die PRIMARYDateigruppe als DEFAULTDateigruppe festlegen:

ALTER DATABASE [DB] MODIFY FILEGROUP [PRIMARY] DEFAULT

Dateigruppe 'xyz' ist ReadOnly

Wenn die Fehlermeldung jedoch folgende lautet:

Msg 5055, Level 16, State 2, Line 88 
Cannot add, remove, or modify file 'xyz_logical_name'. The file is read-only.

... dann müssen Sie die READ_ONLY-Eigenschaft in der xyzDateigruppe entfernen:

ALTER DATABASE [DB] MODIFY FILEGROUP [xyz] READWRITE

Sie sollten nun in der Lage sein, die logische Datei der Dateigruppe und die Dateigruppe selbst zu löschen.

Transaktionen öffnen

Wenn der Dateigruppe, die xyzSie löschen möchten, wirklich keine Datei (logischer_name / pyhsischer_Dateiname) zugeordnet ist , werden durch Ausführen einer Transaktionsprotokollsicherung möglicherweise alle Transaktionen freigegeben, die das weitere Löschen der Dateigruppe behindern.

Wählen Sie 911

Wenn alles andere fehlschlägt, können Sie einen Anruf bei Microsoft eröffnen.


Nicht übereinstimmende Metadaten

Nach weiteren Recherchen hinzugefügt

Anscheinend gibt es Fälle, in denen die Metadaten in der Datenbank nicht den tatsächlichen Standort der Objekte widerspiegeln.

Referenz:
- FIX: Fehler bei der Metadateninkonsistenz nach dem Wechseln von Tabellenpartitionen und dem Löschen entsprechender Dateien und Dateigruppen (Microsoft Support)
- FIX: Ein Fehler tritt auf, wenn Sie versuchen, Dateigruppen oder Partitionsschemata und -funktionen in SQL Server (Microsoft Support) zu löschen oder zu löschen.

Diese beiden Fälle scheinen mit Cumulative Update 3 für SQL Server 2014 SP1 bzw. Cumulative Update 1 für SQL Server 2016 behoben worden zu sein . Sie gelten nicht für Ihre Situation, zeigen jedoch, dass die Metadaten manchmal falsch sein können.

Das Element, das das Löschen Ihrer Dateigruppe zu blockieren scheint, ist der Index, der möglicherweise mit falschen Metadaten gespeichert wird.

Mögliche Lösung

Ziehen Sie in Betracht, den Index neu zu erstellen, auf den Ref90159CCCin der Fehlermeldung verwiesen wird.

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.

Der folgende Artikel beschreibt eine ähnliche Situation und zeigt, wie der Autor den Täter entdeckt und die Situation gelöst hat.

Referenz: SQL Server: Problem mit der Inkonsistenz zwischen Switch-Partition und Metadaten (Blog dbi-services.com)


Suchen Sie nach Objekten, die sich auf veraltete Dateigruppe beziehen

Ich habe dieses Skript manipuliert, um so viele Verstecke wie möglich für Tabellen / Indizes / Partitionen / etc. Zu überprüfen. das könnte sich immer noch auf die abgelegte Dateigruppendatei beziehen:

Bitte ersetzen Sie DEFAULTROmit dem Namen Ihrer veralteten Dateigruppe (zB 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
                  )
           )

Referenz: Mein persönliches Skript

Führen Sie es aus und prüfen Sie, ob Objekte angezeigt werden, die Ihre veraltete Dateigruppe enthalten. Gehen Sie mit dem data_space_idund nicht mit dem Namen. Die Verknüpfungen sollen absichtlich FULL"verwaiste" Referenzen abfangen.

Alternativ können Sie dieses kleinere Skript verwenden, um schnell nach Elementen in der veralteten Dateigruppe zu suchen:

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

Referenz: SQL SERVER - Alle Objekte auflisten, die für alle Dateigruppen in der Datenbank erstellt wurden (SQLAuthority.com)


sp_helpfilegroup: FG_AUDIT groupid 2 filecount 0 keine Dateien
Martin Guth

Datenbank ist in einfachen Wiederherstellungsmodell und es gibt derzeit keine offenen Transaktionen (auf dem Testserver als Ganzes)
Martin Guth

Danke für die Rückmeldung. Könnten Sie diese Informationen zu Ihrer Frage hinzufügen? Ich werde Ihrer Fehlermeldung ( ...CCC_APPLICATION_new...; ist das die temporäre Dateigruppe?) Noch einige Gedanken geben und versuchen, sie in meiner Umgebung zu reproduzieren.
John aka hot2use

1
CCC_APPLICATION_new ist nicht die temporäre Dateigruppe ... es ist die Dateigruppe, in die der Inhalt verschoben wurde ... es sollte in "CCC_APPLICATION" umbenannt werden ... dies funktioniert jedoch nur, wenn die Dateigruppe ohne zugeordnete Datei mit dem Namen CCC_APPLICATION gelöscht wurde oder umbenannt (aber ich möchte nicht, dass es herumhängt)
Martin Guth

1
Zur Verdeutlichung: Ich habe das Problem in zwei verschiedenen Datenbanken ... eine mit der alten Dateigruppe CCC_APPLICATION und der neuen Dateigruppe CCC_APPLICATION_new und eine mit der alten Dateigruppe FG_AUDIT und der neuen Dateigruppe CCC_AUDIT
Martin Guth

2

Nach vier Monaten fand der Microsoft-Support eine Lösung. Es gab tatsächlich eine Tabelle, die sich auf diese vermutlich leere Dateigruppe bezog.

Die Tabelle wurde durch die folgende Aussage identifiziert:

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'

Nachdem die Daten in eine neue Tabelle verschoben und die problematische Tabelle gelöscht wurden, wurde die Dateigruppe erfolgreich entfernt. Das Verschieben der Daten war: Erstellen einer neuen Tabelle mit derselben Struktur und denselben Indizes, Kopieren von Daten über SELECT INTO, Löschen einer alten Tabelle, Umbenennen einer neuen Tabelle (und natürlich für Fremdschlüssel, falls im gesamten Prozess vorhanden) )


Ich habe seit Jahren nach dieser Antwort gesucht. Vielen Dank!
Christian4145
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.