Збій SHRINKFILE - Чому збільшується розмір файлу?


10

Я виконую деякі SHRINKFILEоперації з очищення купки крихітних непотрібних файлів у групі файлів. Для одного із скорочень команда нижче призводить до помилки:

DBCC SHRINKFILE (N'myfile' , EMPTYFILE)'

Ідентифікатор файла x ідентифікатора бази даних x неможливо зменшити, оскільки він або стискається іншим процесом, або порожній

Він не порожній і не стискається. Він працює в базі даних, яку наразі не використовує ніхто, крім мене. Автоматична усадка не ввімкнена і ніколи не була. Тим НЕ менше, були ручні психіатри , виконані в цій базі даних на регулярній основі до мене отримувати мої руки на ньому, якщо це має значення взагалі.

У SQLServerCentral нитка з десятиліття тому пропонує додати до файлу кілька Мб, оскільки це "скидає внутрішній лічильник або комутатор, який говорить про те, що зараз він не знаходиться в середині скорочення".

Це спрацювало - приголомшливо. Але чи може хтось більш детально пояснити, як / чому це працює стосовно внутрішніх служб SQL Server?


1
Не можу сказати тобі відповіді, але заявляю, що це корисний трюк, щоб дізнатися, чи буду я коли-небудь стикатися з цією ситуацією в майбутньому!
Джон Ейсбренер

якщо ви можете спростувати, можливо, якийсь прапор на сторінці заголовка файлу, який встановлюється під час зменшення?
Мартін Сміт

Так, я міг би зробити цей знімок на тестовому екземплярі, але це було продюсером, тому точно не маю розкоші намагатися відтворити його там.
LowlyDBA

Відповіді:


5

Я поскакував на сторінці заголовка файлів, як запропонував у коментарях Мартін Сміт. Я думаю, що це частина відповіді, але в основному це припущення, засновані на спостереженні за змінами значень прапорця сторінки заголовка файлу між виконанням скорочень та іншими операціями.


Спочатку я створив базу даних, на яку потрібно перевірити, включаючи вторинну файлову групу:

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

Я переглянув "сторінку 0" для другого файлу, який є file_id 3:

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

Там називається поле, m_flagBitsяке має значення 0x208.

Якщо я порожній цей файл:

DBCC SHRINKFILE (N'ShrinkFile_Test_Secondary' , EMPTYFILE);

Це m_flagbitsполе залишається таким же ( 0x208). Це не так цікаво, але зараз я опинився в ситуації, про яку ви повідомили: якщо я спробую спустошити файл ще раз, я отримаю цю помилку:

Ідентифікатор файлу 3 Ідентифікатора бази даних 19 неможливо зменшити, оскільки він або стискається іншим процесом, або порожній.

Я спробую виростити файл (рішення, яке працювало для вас):

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

Зараз m_flagbitsє 0x8!

На цьому етапі повторне випорожнення файлу повертає значення, 0x208як ви могли очікувати.

Що мені здається цікавим, це те, що якщо я це роблю після вирощування файлу назад (значення AKA flagbits є 0x8):

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

Файл позначений як is_read_onlyу sys.databasesтаблиці та m_flagbitsповертається до 0x208. Тому, схоже, є якийсь подібний прапор рівня файлу, встановлений під час скорочення файлу та встановлення його лише для читання.

Я найкраще здогадуюсь, що це значення використовується разом із деяким іншим (внутрішнім) прапором, щоб вказати, що файл може бути скороченим. Зростаючий файл, схоже, скасовує цей прапор (принаймні той, який видно в m_flagbits).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.