Tidak dapat menghapus filegroup tanpa file yang terkait

8

Saya mengalami beberapa pesan kesalahan aneh pada SQL Server 2017 CU3. Saya memigrasikan basis data dan mengatur ulang grup-grup film. Dengan "mengatur ulang" maksud saya bahwa saya menggunakan prosedur tersimpan yang membuat fungsi partisi dan skema partisi pada filegroup baru untuk objek, membangun kembali indeks saat mempartisi dan kemudian menghapus partisi.

Pada akhirnya saya mendapatkan beberapa filegroup kosong. File - file mereka dihapus . Juga filegroup itu sendiri dihapus. Ini bekerja dengan baik dalam banyak kasus. Namun untuk dua database saya dihapus file ... memiliki filegroup dibiarkan tanpa file terkait tapi

ALTER DATABASE REMOVE FILEGROUP

melempar kesalahan 5042:

Filegroup 'xyz' tidak dapat dihapus karena tidak kosong.

Pertanyaan

Bagaimana saya bisa menyingkirkan filegroup kosong itu ... apa masalahnya?

Saya sudah membaca beberapa masalah umum namun tidak ada dalam sistem saya:

  • Diperiksa:

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

    0 rows ... tidak ada objek partisi yang tersisa di database

  • UPDATE STATISTICS untuk semua objek dalam database

    tidak berpengaruh

  • Cek indeks pada filegroup:

    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 baris

  • Memeriksa objek di filegroup:

    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 baris

Saya juga memberi DBCC SHRINKFILEparameter EMPTYFILEmencoba sebelum menghapus file dari filegroup. Itu tidak benar-benar masuk akal bagi saya namun saya membaca solusi untuk menggambarkan itu sebagai perbaikan. Lagi pula tidak berpengaruh.


Saya mendapat harapan membaca pertanyaan ini tentang kesalahan server dan mencoba yang berikut:

  • Perbarui semua statistik
  • Hapus semua statistik yang tidak terkait dengan indeks

Namun ini tidak berpengaruh. Saya masih memiliki filegroup tanpa file yang terkait dan filegroup tidak dapat dihapus. Saya benar-benar bingung karena ini terjadi di beberapa database dan tidak di yang lain (dengan struktur yang sama). Ketika saya tampil DBCC CHECK FILEGROUPdi filegroup kosong ini saya mendapatkan banyak pesan kesalahan seperti berikut:

Tidak dapat memproses rowset ID 72057594712162304 objek "STORY_TRANSLATIONSCCC" (ID 120387498), indeks "Ref90159CCC" (ID 2), karena ia berada di filegroup "CCC_APPLICATION_new" (ID 8), yang tidak dicentang.

Hasil DBCC untuk 'STORY_TRANSLATIONSCCC'. Ada 0 baris dalam 0 halaman untuk objek "STORY_TRANSLATIONSCCC".

Apakah ini normal atau apakah ini menunjuk ke sesuatu yang tidak biasa?

Pertanyaan ini mungkin merupakan duplikat, namun saya tidak dapat menemukan perbaikan yang berfungsi untuk saya dalam pertanyaan lain di dba.stackexchange. Silakan lihat daftar apa yang sudah saya coba. Ini identik dengan solusi yang dijelaskan dalam Tidak dapat menghapus filegroup yang tidak digunakan .

Keterangan lebih lanjut

Mungkin membantu memahami apa yang saya lakukan sebelum kesalahan terjadi. Saya merencanakan migrasi ke server baru. Saat ini saya sedang menguji ini pada contoh uji. Database dipulihkan dari server prod dan model pemulihan dialihkan ke yang sederhana. Tujuan saya adalah merestrukturisasi filegroup dan pindah dari model dengan satu file per filegroup ke model dengan dua file per grup file. Untuk mencapai itu saya membuat filegroup kosong baru dengan masing-masing dua file dan memindahkan data. Sayangnya sebagian besar objek memiliki Data LOB (XML dan biner) ... jadi saya memanfaatkan partisi sebagai penolong untuk memindahkan data-lob juga. Pada akhirnya semua data berada di filegroup baru dan filegroup lama kosong. Lalu saya menghapus semua file dan menghapus filegroup masing-masing juga. Filegroup utama tetap dan hanya mendapatkan file lain ditambahkan.pertanyaan saya . Proses ini berfungsi dengan baik tetapi dalam dua basis data file dapat dihapus tetapi grupfile tidak. Anehnya struktur basis data ini harus sama dengan struktur basis data lain jika tidak ada masalah yang dihadapi dalam proses pemindahan data dan menghapus filegroup lama.

Jadi, inilah daftar filegroup dan file dari dua database di mana masalah terjadi:

  1. CCC_GENTE

sebelum

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

setelah

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

Saya harap itu sedikit membantu. Ada juga database kedua di mana nama filegroup berbeda tetapi saya biarkan itu untuk singkatnya.

Martin Guth
sumber
1
Saya tahu itu tidak menyebutkan SQL2017 tapi saya ingin tahu apakah bug itu masih ada di tahun 2017? support.microsoft.com/en-us/help/3132058/…
SqlWorldWide
@SqlWorldWide: Terima kasih atas tautannya. Namun saya tidak memiliki indeks teks lengkap dan menghapus fungsi partisi dan skema sendiri ... karena itu saya kira tautan itu tidak berlaku untuk masalah saya.
Martin Guth
Bisakah Anda mencetak seluruh kesalahan 5042, negara memberikan apa masalahnya.
Sean Gallardy - Pensiunan Pengguna
@ SeanGallardy-Microsoft: Pesan 5042, Level 16, Status 8, Baris 1 Filegroup 'FG_AUDIT' tidak dapat dihapus karena tidak kosong.
Martin Guth
Terima kasih :) State 8 berarti filegroup sedang digunakan oleh suatu objek. Ini berbeda dari artikel dukungan (itu menyatakan 12 yang berarti fg digunakan oleh skema partisi). Yang aneh adalah Anda mengatakan filegroup tidak memiliki file di dalamnya. Saya berasumsi beberapa cadangan log (jika penuh / massal) telah diambil sejak masalah terjadi?
Sean Gallardy - Pensiunan Pengguna

Jawaban:

4

Periksa Grup Grup dalam Basis Data

Verifikasi bahwa filegroup tidak memiliki file yang tersisa yang dilampirkan dengan mengeluarkan perintah berikut:

use [DB]
go
sp_helpfilegroup 

Ini akan menghasilkan daftar grup-grup film:

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

... dan kemudian untuk setiap filegroup yang terdaftar, jalankan

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

Outputnya mungkin terlihat seperti ini:

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

.... dan output kedua mungkin:

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

Menghapus Filegroup

Jika Anda masih memiliki file yang dikaitkan dengan salah satu dari grup-grup Anda, maka perintah lengkap untuk menghapus file-file logis dari grup-grup dan grup-fileg itu sendiri adalah:

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

Filegroup 'xyz' Apakah Default

Jika Anda menerima pesan kesalahan saat mencoba menghapus file logis filegroup yang terlihat seperti ini:

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.

... maka Anda harus mengatur PRIMARYfilegroup sebagai DEFAULTfilegroup:

ALTER DATABASE [DB] MODIFY FILEGROUP [PRIMARY] DEFAULT

Filegroup 'xyz' Hanya Dapat Dibaca

Namun, jika pesan kesalahannya adalah sebagai berikut:

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

... maka Anda harus menghapus properti READ_ONLY di xyzfilegroup:

ALTER DATABASE [DB] MODIFY FILEGROUP [xyz] READWRITE

Anda sekarang harus dapat menjatuhkan file logis filegroup dan filegroup itu sendiri.

Buka Transaksi

Jika Anda benar-benar tidak memiliki file (logical_name / pyhsical_file_name) yang terkait dengan filegroup yang xyzAnda coba hapus, maka melakukan pencadangan log transaksi dapat melepaskan transaksi apa pun yang menghalangi penghapusan filegroup lebih lanjut.

Tekan 911

Jika semuanya gagal, Anda mungkin ingin mempertimbangkan untuk membuka panggilan dengan Microsoft.


Ketidakcocokan Metadata

Ditambahkan setelah penelitian lebih lanjut

Rupanya ada beberapa kasus ketika metadata dalam database tidak mencerminkan lokasi sebenarnya dari objek.

Referensi:
- MEMPERBAIKI: Kesalahan inkonsistensi metadata setelah Anda beralih partisi tabel dan menjatuhkan file dan filegroup yang sesuai (Dukungan Microsoft)
- FIX: Kesalahan terjadi ketika Anda mencoba untuk menjatuhkan atau menghapus grup-grup filem atau skema partisi dan fungsi dalam SQL Server (Dukungan Microsoft)

Kedua kasus ini tampaknya telah diselesaikan dengan Pembaruan Kumulatif 3 untuk SQL Server 2014 SP1 dan Pembaruan Kumulatif 1 untuk SQL Server 2016 masing-masing. Mereka tidak berlaku untuk situasi Anda, tetapi mereka menunjukkan bahwa kadang-kadang metadata bisa salah.

Item yang tampaknya memblokir penghapusan filegroup Anda adalah indeks, yang mungkin disimpan dengan meta-data yang salah.

Kemungkinan Solusi

Pertimbangkan membangun kembali indeks Ref90159CCCyang dirujuk dalam pesan kesalahan.

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.

Artikel berikut menjelaskan situasi yang sama dan menunjukkan bagaimana penulis mendeteksi pelakunya dan menyelesaikan situasi.

Referensi: SQL Server: beralih partisi dan masalah inkonsistensi metadata (Blog dbi-services.com)


Temukan Objek yang Berhubungan dengan Grup Filsay Usang

Saya memasang skrip ini untuk memeriksa sebanyak mungkin tempat persembunyian untuk tabel / indeks / partisi / dll. yang mungkin masih berkaitan dengan file filegroup yang dijatuhkan:

Silakan ganti DEFAULTROdengan nama filegroup usang Anda (mis. 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
                  )
           )

Referensi: Naskah pribadi saya

Jalankan dan lihat apakah ada objek yang ditampilkan yang mengandung filegroup usang Anda. Pergilah dengan data_space_idalih - alih dengan nama. Gabungan tersebut sengaja FULLmenangkap referensi "yatim".

Atau gunakan skrip yang lebih kecil ini untuk memeriksa item di filegroup yang sudah usang:

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

Referensi: SQL SERVER - Daftar Semua Objek yang Dibuat di Semua Grup Grup di Database (SQLAuthority.com)

John alias hot2use
sumber
sp_helpfilegroup: FG_AUDIT groupid 2 filecount 0 tanpa file
Martin Guth
database dalam model pemulihan sederhana dan saat ini tidak ada transaksi terbuka (pada testserver secara keseluruhan)
Martin Guth
Terima kasih untuk umpan baliknya. Bisakah Anda menambahkan informasi ini ke pertanyaan Anda? Saya akan memberikan pesan kesalahan Anda ( ...CCC_APPLICATION_new...; apakah itu grup berita sementara?) Beberapa pemikiran lagi dan mencoba mereproduksi di lingkungan saya.
John aka hot2use
1
CCC_APPLICATION_new bukan filegroup sementara ... itu adalah filegroup yang isinya telah dipindahkan ke ... itu harus diubah namanya menjadi "CCC_APPLICATION" ... namun ini hanya berfungsi jika filegroup tanpa file yang terkait bernama CCC_APPLICATION telah dihapus atau berganti nama (tetapi tidak ingin berkeliaran)
Martin Guth
1
untuk klarifikasi: Saya mendapatkan masalah dalam dua basis data yang berbeda ... satu dengan CCC_APPLICATION filegroup lama dan CCC_APPLICATION filegroup baru dan satu lagi dengan filegroup lama FG_AUDIT dan filegroup baru CCC_AUDIT
Martin Guth
2

Setelah empat bulan, Dukungan Microsoft menemukan solusi. Memang ada tabel yang merujuk pada filegroup yang mungkin kosong ini.

Tabel tersebut diidentifikasi oleh pernyataan berikut:

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'

Setelah memindahkan data ke tabel baru dan menjatuhkan tabel bermasalah filegroup berhasil dihapus. Proses memindahkan data adalah: membuat tabel baru dengan struktur dan indeks yang sama, menyalin data melalui SELECT INTO, letakkan tabel lama, ganti nama tabel baru (dan tentu saja urus kunci asing jika ada dalam seluruh proses) )

Martin Guth
sumber
Saya mencari jawaban ini selama bertahun-tahun sekarang. Terima kasih banyak!
Christian4145