web-dev-qa-db-fra.com

Échec de la frénculterie - Pourquoi l'augmentation de la taille du fichier résoudra-t-elle?

Je gère des opérations SHRINKFILE Opérations pour nettoyer un tas de fichiers minuscules et inutiles d'un groupe de fichiers. Pour l'un des rétrécissements, la commande ci-dessous donne une erreur:

DBCC SHRINKFILE (N'myfile' , EMPTYFILE)'

ID de fichier x de la base de données ID x ne peut pas être rétréci car il est soit rétréci par un autre processus ou est vide

Ce n'est pas vide ni rétréci. Il est exécuté sur une base de données non utilisée par personne, à l'exception de moi-même. Le rétrécissement automatique n'est pas activé et n'a jamais été. Cependant, il étaient rétrécit manuellement rétrécit sur cette base de données de manière régulière avant de me mettre la main dessus, si cela importe du tout.

Sur - SQLServerCentral , un thread d'une décennie il y a une décennie suggère d'ajouter quelques MB au fichier car "réinitialise un compteur interne ou un commutateur qui lui dit que ce n'est pas au milieu d'un rétrécissement maintenant".

Cela a fonctionné - génial. Mais quelqu'un peut-il expliquer avec plus de détails comment/pourquoi cela fonctionne en ce qui concerne les internaux SQL Server?

10

J'ai piqué dans la page d'en-tête de 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 apportées aux valeurs de drapeau de la page d'en-tête de fichier entre les rétrécissements et d'autres opérations.


J'ai d'abord créé une base de données à tester avec, 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

La page I examinée "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 cela a une valeur de 0x208.

Si je vide ce fichier:

DBCC SHRINKFILE (N'ShrinkFile_Test_Secondary' , EMPTYFILE);

Ce m_flagbits Le champ reste le même (0x208). Pas si intéressant, mais maintenant je suis dans la situation que vous avez signalé: Si j'essaie de vider le fichier à nouveau, je reçois cette erreur:

ID de fichier 3 de la base de données ID 19 ne peut pas être rétréci car il est soit réduit par un autre processus ou est vide.

Je vais essayer de développer le fichier (la solution qui a fonctionné pour vous):

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

À présent m_flagbits est 0x8!

À ce stade, vider le fichier à nouveau réussi retourne la valeur à 0x208 Comme vous pouvez vous attendre.

La chose que je trouve intéressante est que si je le fais après avoir grandi le fichier de retour (la valeur de flagbits 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 table et m_flagbits est revenu sur 0x208. Il apparaît donc qu'il y a un drapeau de niveau de fichier similaire lors de la rétrécissement d'un fichier et lors du réglage à la lecture seule.

Ma meilleure estimation est que cette valeur est utilisée avec un autre drapeau (interne) pour indiquer qu'un fichier est éligible pour être rétréci. La croissance du fichier semble non définie que le drapeau (au moins celui visible dans m_flagbits).

5
Josh Darnell