Błąd SHRINKFILE - Dlaczego zwiększenie rozmiaru pliku to rozwiązuje?


10

Przeprowadzam kilka SHRINKFILEoperacji, aby oczyścić kilka małych, niepotrzebnych plików w grupie plików. W przypadku jednego z obkurczeń poniższe polecenie powoduje błąd:

DBCC SHRINKFILE (N'myfile' , EMPTYFILE)'

Identyfikator pliku x identyfikatora bazy danych x nie może zostać zmniejszony, ponieważ jest on zmniejszany przez inny proces lub jest pusty

Nie jest pusty ani się nie kurczy. Jest uruchamiany w bazie danych, która nie jest obecnie używana przez nikogo oprócz mnie. Automatyczne zmniejszanie nie jest włączone i nigdy nie było. Jednak w tej bazie danych regularnie dokonywano ręcznych obkurczeń, zanim dotarłem do niej, jeśli to w ogóle ma znaczenie.

W SQLServerCentral wątek sprzed dekady sugeruje dodanie do pliku kilku MB, ponieważ to „resetuje wewnętrzny licznik lub przełącznik, który mówi, że nie jest teraz w trakcie zmniejszania”.

To zadziałało - niesamowite. Ale czy ktoś może bardziej szczegółowo wyjaśnić, w jaki sposób / dlaczego to działa w odniesieniu do wewnętrznych elementów SQL Server?


1
Nie mogłem odpowiedzieć na pytanie, ale głosowanie, ponieważ jest to przydatna sztuczka, aby wiedzieć, czy kiedykolwiek napotkam taką sytuację w przyszłości!
— John Eisbrener,

jeśli możesz repro, może jakaś flaga na stronie nagłówka pliku, która jest ustawiana podczas zmniejszania?
— Martin Smith,

Tak, mógłbym dać temu szansę na testową instancję, ale to było cudowne, więc zdecydowanie nie mam luksusu, próbując go tam odtworzyć.
— LowlyDBA

Odpowiedzi:


5

Przeszukiwałem stronę nagłówka pliku, jak sugerował Martin Smith w komentarzach. Myślę, że jest to część odpowiedzi, ale jest to głównie spekulacja oparta na obserwowaniu zmian wartości flag strony nagłówka pliku między wykonywaniem skurczów a innymi operacjami.


Najpierw utworzyłem bazę danych do testowania, w tym dodatkową grupę plików:

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

Spojrzałem na „stronę 0” dla drugiego pliku, którym jest file_id 3:

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

Istnieje pole o nazwie, m_flagBitsktóre ma wartość 0x208.

Jeśli opróżnię ten plik:

DBCC SHRINKFILE (N'ShrinkFile_Test_Secondary' , EMPTYFILE);

To m_flagbitspole pozostaje takie samo ( 0x208). Nie tak interesujące, ale teraz jestem w sytuacji, którą zgłosiłeś: jeśli spróbuję ponownie opróżnić plik, pojawia się ten błąd:

Identyfikator pliku 3 identyfikatora bazy danych 19 nie może zostać zmniejszony, ponieważ jest albo zmniejszany przez inny proces, albo jest pusty.

Spróbuję rozbudować plik (rozwiązanie, które Ci się udało):

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

Teraz m_flagbitsjest 0x8!

W tym momencie ponowne opróżnienie pliku zakończy się powodzeniem i zwraca wartość, 0x208zgodnie z oczekiwaniami.

Interesujące jest dla mnie to, że jeśli zrobię to po wyodrębnieniu pliku (wartość flagówek AKA to 0x8):

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

Plik jest oznaczony jak is_read_onlyw sys.databasestabeli i m_flagbitsustawiony jest z powrotem na 0x208. Wygląda więc na to, że podczas zmniejszania pliku i ustawiania go jako tylko do odczytu ustawiono podobną flagę na poziomie pliku.

Domyślam się, że ta wartość jest używana wraz z jakąś inną (wewnętrzną) flagą wskazującą, że plik kwalifikuje się do zmniejszenia. Wydaje się, że powiększenie pliku powoduje wyłączenie tej flagi (przynajmniej tej widocznej w m_flagbits).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.