SHRINKFILE Failure - Mengapa peningkatan ukuran file bisa mengatasinya?

10

Saya menjalankan beberapa SHRINKFILEoperasi untuk membersihkan banyak file kecil yang tidak perlu dalam sebuah filegroup. Untuk salah satu psikiater, perintah di bawah ini menghasilkan kesalahan:

DBCC SHRINKFILE (N'myfile' , EMPTYFILE)'

ID file x dari ID basis data x tidak dapat menyusut karena sedang menyusut oleh proses lain atau kosong

Itu tidak kosong atau menyusut. Sedang dijalankan pada basis data yang saat ini tidak digunakan oleh siapa pun kecuali saya. Penyusutan otomatis tidak diaktifkan dan tidak pernah ada. Namun, ada yang menyusut pengguna dilakukan pada database ini secara teratur sebelum saya mendapatkan tangan saya di atasnya, jika hal-hal yang sama sekali.

Pada SQLServerCentral , utas dari satu dekade lalu menyarankan menambahkan beberapa MB ke file karena itu "me-reset penghitung internal atau switch yang mengatakan itu bukan di tengah menyusut sekarang."

Ini berhasil - luar biasa. Tapi adakah yang bisa menjelaskan dengan lebih rinci bagaimana / mengapa ini bekerja dalam kaitannya dengan SQL Server internal?

LowlyDBA
sumber
1
Tidak dapat memberi tahu Anda jawabannya, tetapi tetap upvoting karena itu adalah trik yang berguna untuk mengetahui apakah saya pernah mengalami situasi ini di masa depan!
John Eisbrener
jika Anda dapat repro, mungkin beberapa flag pada halaman header file yang diset selama menyusut?
Martin Smith
Ya saya mungkin memberikan suntikan itu pada contoh uji, tapi ini adalah dorongan jadi pasti tidak memiliki kemewahan mencoba mereproduksi di sana.
LowlyDBA

Jawaban:

5

Saya mencari-cari di halaman file header, seperti yang disarankan oleh Martin Smith dalam komentar. Saya pikir ini adalah bagian dari jawaban, tetapi sebagian besar spekulasi berdasarkan mengamati perubahan pada nilai-nilai bendera halaman header file antara melakukan menyusut dan operasi lainnya.


Pertama saya membuat basis data untuk diuji, termasuk filegroup sekunder:

CREATE DATABASE [Shrinkfile_Test]
ON PRIMARY
(
    NAME = N'Shrinkfile_Test',
    FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\Shrinkfile_Test.mdf',
    SIZE = 8192KB,
    FILEGROWTH = 65536KB
),
FILEGROUP [SECONDARY]
(
    NAME = N'ShrinkFile_Test_Secondary',
    FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\ShrinkFile_Test_Secondary.ndf',
    SIZE = 1024KB,
    FILEGROWTH = 65536KB
)
LOG ON
(
    NAME = N'Shrinkfile_Test_log',
    FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\Shrinkfile_Test_log.ldf',
    SIZE = 73728KB,
    FILEGROWTH = 65536KB 
)
GO

USE Shrinkfile_Test;
GO

Saya melihat "halaman 0" untuk file sekunder, yaitu file_id 3:

DBCC TRACEON (3604);
GO
DBCC PAGE (N'Shrinkfile_Test', 3, 0, 3);

Ada bidang yang disebut m_flagBitsmemiliki nilai 0x208.

Jika saya mengosongkan file ini:

DBCC SHRINKFILE (N'ShrinkFile_Test_Secondary' , EMPTYFILE);

Bahwa m_flagbitslapangan tetap sama ( 0x208). Tidak terlalu menarik, tapi sekarang saya dalam situasi yang Anda laporkan: jika saya mencoba mengosongkan file lagi, saya mendapatkan kesalahan ini:

File ID 3 dari database ID 19 tidak dapat menyusut karena sedang menyusut oleh proses lain atau kosong.

Saya akan mencoba menumbuhkan file (solusi yang bekerja untuk Anda):

ALTER DATABASE ShrinkFile_Test
MODIFY FILE
(
    NAME = ShrinkFile_Test_Secondary,
    SIZE = 1025KB
);
GO

Sekarang m_flagbitsadalah 0x8!

Pada titik ini, mengosongkan file lagi berhasil mengembalikan nilai 0x208seperti yang Anda harapkan.

Hal yang saya temukan menarik adalah jika saya melakukan ini setelah menumbuhkan kembali file (nilai flagbits AKA adalah 0x8):

USE [master]
GO
ALTER DATABASE [Shrinkfile_Test] MODIFY FILEGROUP [SECONDARY] READONLY
GO

File ditandai seperti is_read_onlypada sys.databasestabel, dan m_flagbitsdiatur kembali ke 0x208. Jadi tampaknya ada beberapa flag tingkat file serupa yang diatur ketika menyusutkan file dan ketika mengatur hanya untuk membaca.

Tebakan terbaik saya adalah bahwa nilai ini digunakan bersama dengan beberapa lainnya (internal) bendera untuk menunjukkan bahwa file memenuhi syarat untuk menyusut. Tumbuhkan file tampaknya membatalkan set flag itu (setidaknya yang terlihat di m_flagbits).

Josh Darnell
sumber