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_flagBits
które ma wartość 0x208
.
Jeśli opróżnię ten plik:
DBCC SHRINKFILE (N'ShrinkFile_Test_Secondary' , EMPTYFILE);
To m_flagbits
pole 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_flagbits
jest 0x8
!
W tym momencie ponowne opróżnienie pliku zakończy się powodzeniem i zwraca wartość, 0x208
zgodnie 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_only
w sys.databases
tabeli i m_flagbits
ustawiony 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
).