J'ai fouillé dans la page d'en-tête du fichier, comme suggéré par Martin Smith dans les commentaires. Je pense que cela fait partie de la réponse, mais il s'agit principalement de spéculations basées sur l'observation des modifications des valeurs d'indicateur de page d'en-tête de fichier entre l'exécution de rétrécissements et d'autres opérations.
J'ai d'abord créé une base de données pour tester, y compris un groupe de fichiers secondaire:
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
J'ai regardé la "page 0" pour le fichier secondaire, qui est file_id 3:
DBCC TRACEON (3604);
GO
DBCC PAGE (N'Shrinkfile_Test', 3, 0, 3);
Il y a un champ appelé m_flagBits
qui a une valeur de 0x208
.
Si je vide ce fichier:
DBCC SHRINKFILE (N'ShrinkFile_Test_Secondary' , EMPTYFILE);
Ce m_flagbits
champ reste le même ( 0x208
). Pas si intéressant, mais maintenant je suis dans la situation que vous avez signalée: si j'essaie de vider à nouveau le fichier, j'obtiens cette erreur:
L'ID de fichier 3 de l'ID de base de données 19 ne peut pas être réduit car il est en cours de réduction par un autre processus ou est vide.
Je vais essayer d'agrandir le fichier (la solution qui a fonctionné pour vous):
ALTER DATABASE ShrinkFile_Test
MODIFY FILE
(
NAME = ShrinkFile_Test_Secondary,
SIZE = 1025KB
);
GO
Maintenant m_flagbits
est 0x8
!
À ce stade, la vidange du fichier réussit à nouveau renvoie la valeur 0x208
comme vous pouvez vous y attendre.
La chose que je trouve intéressante est que si je fais cela après avoir repoussé le fichier (la valeur des bits de drapeau AKA est 0x8
):
USE [master]
GO
ALTER DATABASE [Shrinkfile_Test] MODIFY FILEGROUP [SECONDARY] READONLY
GO
Le fichier est marqué comme is_read_only
dans le sys.databases
tableau et m_flagbits
est remis à 0x208
. Il semble donc qu'un indicateur de niveau de fichier similaire soit défini lors de la réduction d'un fichier et lors de sa définition en lecture seule.
Ma meilleure supposition est que cette valeur est utilisée avec un autre indicateur (interne) pour indiquer qu'un fichier peut être réduit. Agrandir le fichier semble désactiver ce drapeau (au moins celui visible dans m_flagbits
).