DBCC SHRINKFILE (Transact-SQL)

Применимо к:SQL ServerБаза данных SQL AzureУправляемый экземпляр SQL AzureБаза данных SQL в Microsoft Fabric

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

Используйте DBCC SHRINKFILE только по необходимости, так как уменьшение — это долгосрочная и ресурсоёмкая операция.

Примечание.

Не воспринимайте операции по уменьшению усадки как регулярное обслуживание. Файлы данных и журналов, которые растут из-за регулярных повторяющихся бизнес-операций, не требуют операций сжатия.

Соглашения о синтаксисе Transact-SQL

Синтаксис

DBCC SHRINKFILE
(
    { file_name | file_id }
    { [ , EMPTYFILE ]
    | [ [ , target_size ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ]
    }
)
[ WITH
  {
      [ WAIT_AT_LOW_PRIORITY
        [ (
            <wait_at_low_priority_option_list>
        ) ]
      ]
      [ , NO_INFOMSGS ]
  }
]

<wait_at_low_priority_option_list> ::=
    <wait_at_low_priority_option>
    | <wait_at_low_priority_option_list> , <wait_at_low_priority_option>

<wait_at_low_priority_option> ::=
    ABORT_AFTER_WAIT = { SELF | BLOCKERS }

Аргументы

file_name

Логичное название файла для уменьшения.

file_id

Идентификационный (ID) номер файла должен уменьшиться. Чтобы получить идентификатор файла, используйте системную функцию FILE_IDEX или выполните запрос к представлению каталога sys.database_files в текущей базе данных.

target_size

Целое число, представляющее новый размер мегабайта файла. Если вы установите target_size или 0 не указываете его, DBCC SHRINKFILE это уменьшает размер файла до его созданного размера.

Вы можете уменьшить размер пустого файла по умолчанию с помощью DBCC SHRINKFILE <target_size>. Например, при создании файла с размером 5 МБ и последующем уменьшении размера до 3 МБ, в то время как файл остается пустым, размер файла по умолчанию задается равным 3 МБ. Это правило применимо только к пустым файлам, в которых никогда не содержались данные.

Контейнеры файловых групп FILESTREAM не поддерживают этот параметр.

При указании DBCC SHRINKFILE пытается уменьшить размер файла до target_size. Используемые страницы в освобождаемой области файла перемещаются в свободное пространство в сохраняемых областях файла. Например, с файлом DBCC SHRINKFILE данных размером 10 МБ операция с 8target_size перемещает все использованные страницы в последние 2 МБ файла на любые нераспределенные страницы в первом 8 МБ файла. DBCC SHRINKFILE не сжимает файл после необходимого размера сохраненных данных. Например, если используется 7 МБ файла данных размером 10 МБ, DBCC SHRINKFILE инструкция с target_size 6 уменьшает размер файла до 7 МБ, а не 6 МБ.

Если указать target_size с TRUNCATEONLY, DBCC SHRINKFILE возможно, не освободится свободное место в конце файла.

ПУСТОЙФАЙЛ

Переносит все данные из указанного файла в другие файлы в той же файловой группе. Другими словами, EMPTYFILE перенос данных из указанного файла в другие файлы в той же файловой группе. EMPTYFILE гарантирует, что новые данные не добавляются в файл, несмотря на то, что этот файл не только для чтения. Вы можете использовать ALTER DATABASE оператор для удаления файла. Если вы используете ALTER DATABASE оператор для изменения размера файла, флаг только для чтения сбрасывается, и можно добавить данные.

Для контейнеров файловой группы FILESTREAM нельзя использовать ALTER DATABASE для удаления файла, пока сборщик мусора FILESTREAM не будет запущен и удален все ненужные файлы контейнеров файловой группы, EMPTYFILE скопированные в другой контейнер. Дополнительные сведения см. в разделе sp_filestream_force_garbage_collection. Для получения информации об удалении контейнера FILESTREAM см. соответствующий раздел вALTER DATABASE разделе Опции файлов и групп файлов

EMPTYFILEне поддерживается в База данных SQL Azure, База данных SQL Azure Hyperscale или SQL Database в Microsoft Fabric.

NOTRUNCATE

Позволяет переместить распределенные страницы из конца файла данных на нераспределенные страницы в начале файла с указанием или без указания target_percent. Свободное место в конце файла не возвращается в операционную систему, а физический размер файла не изменяется. Поэтому, если NOTRUNCATE задано, файл не сжимается.

NOTRUNCATE применимо только к файлам данных. Файлы журнала не затрагиваются.

Контейнеры файловых групп FILESTREAM не поддерживают этот параметр.

УСЕЧЬ ТОЛЬКО

Освобождает все свободное место в конце файла в операционной системе, но не выполняет никаких перемещений страниц внутри файла. Файл данных сокращается только до последнего выделенного экстента.

Если target_size указан с TRUNCATEONLY, свободное место в конце файла может быть не выпущено.

Эта TRUNCATEONLY опция не перемещает информацию в журнале, но удаляет неактивные виртуальные файлы журнала (VLF) из конца файла журнала. Контейнеры файловых групп FILESTREAM не поддерживают этот параметр.

С NO_INFOMSGS

Подавляет вывод всех информационных сообщений.

WAIT_AT_LOW_PRIORITY с операциями сжатия

Применяется к: SQL Server 2022 (16.x) и более поздним версиям, База данных SQL Azure, Управляемый экземпляр SQL Azure, SQL базе данных в Microsoft Fabric

Функция ожидания при низком приоритете снижает борьбу за блокировку во время операции уменьшения. Для получения дополнительной информации см . раздел Понимание проблем параллелизма с DBCC SHRINKFILE.

Эта функция похожа на WAIT_AT_LOW_PRIORITY с операциями индексирования в режиме "в сети", с некоторыми различиями.

  • Вы не можете указать эту ABORT_AFTER_WAIT опцию NONE.
  • Ты не можешь настроить эту MAX_DURATION опцию. Тайм-аут блокировки низкого приоритета для операции по уменьшению всегда составляет одну минуту.

ОЖИДАНИЕ_С_НИЗКИМ_ПРИОРИТЕТОМ

Когда команда уменьшения выполняется в WAIT_AT_LOW_PRIORITY режиме, запросы, требующие блокировки стабильности схемы (Sch-S) на страницах Index Allocation Map (IAM ), не блокируются операцией уменьшения. Однако операция уменьшения может быть заблокирована блокировкой Sch-S на странице IAM. Shrink продолжает выполняться только тогда, когда сможет получить блокировку изменения схемы (Sch-M) на необходимой IAM-странице.

Если операция уменьшения в WAIT_AT_LOW_PRIORITY режиме не может получить этот блокировку из-за длительного запроса, удерживающего Sch-S блокировку, операция уменьшения времени заканчивается с ошибкой 49516, например: Msg 49516, Level 16, State 1, Line 134 Shrink timeout waiting to acquire schema modify lock in WLP mode to process IAM pageID 1:2865 on database ID 5.

{ ABORT_AFTER_WAIT = [ SELF | БЛОКИРОВЩИКИ ] }

Применимо к: SQL Server (SQL Server 2022 (16.x) и более поздние версии), База данных SQL Azure, SQL базе данных в Microsoft Fabric.

  • SELF

    SELF — параметр по умолчанию. Завершите операцию уменьшения файла, выполняемую в данный момент, не предпринимая дополнительных действий.

  • BLOCKERS

    Остановить все пользовательские транзакции, в данный момент блокирующие операцию сжатия файла, чтобы можно было продолжить данную операцию. Для этой BLOCKERS опции требуется, чтобы у входа ALTER ANY CONNECTION был доступ к OR KILL DATABASE CONNECTION .

Результирующий набор

В приведенной ниже таблице описаны столбцы результирующего набора.

Имя столбца Описание
DbId Идентификационный номер базы данных файла, ядро СУБД пытался уменьшиться.
FileId Идентификационный номер файла, ядро СУБД попытался сжаться.
CurrentSize Количество 8-килобайтных страниц, занятых файлом в настоящее время.
MinimumSize Минимальное количество 8-килобайтных страниц, которое может занимать файл. Это число соответствует минимальному размеру файла при его создании.
UsedPages Количество 8-килобайтных страниц, используемых файлом в настоящее время.
EstimatedPages Количество страниц размером 8 КБ, на которые ядро СУБД оценивается, что файл может сократиться.

Замечания

DBCC SHRINKFILE применяется к файлам текущей базы данных. Для получения дополнительной информации о том, как изменить текущую базу данных, см. USE.

Вы можете остановить DBCC SHRINKFILE операции в любой момент и сохранить все завершенные работы. Если вы используете EMPTYFILE параметр и отменяете операцию, файл не помечается, чтобы предотвратить добавление дополнительных данных.

Другие пользователи могут работать в базе данных во время сжатия файлов; База данных не должна находиться в однопользовательском режиме. Для сжатия системных баз данных не требуется запускать экземпляр SQL Server в однопользовательском режиме.

Известные проблемы

Применяется к: SQL Server, База данных SQL Azure, SQL database in Microsoft Fabric, Управляемый экземпляр SQL Azure, выделенному Azure Synapse Analytics

  • В версиях SQL Server ранее SQL Server 2025 (17.x), страницы, используемые для столбцов больших объектов (LOB) (varbinary(max), varchar(max) и nvarchar(max)) в сжатых сегментах columnstore, нельзя перемещать по DBCC SHRINKDATABASE и DBCC SHRINKFILE. Дополнительные сведения см. в статье "Новые возможности индексов columnstore".

Общие сведения о проблемах параллелизма с DBCC SHRINKFILE

Команды уменьшения базы данных и уменьшения файлов могут привести к проблемам с параллельностью, особенно при активном обслуживании, таком как восстановление индексов, или в условиях напряжённой онлайн-обработки транзакций (OLTP).

Например, пользовательский запрос может получить блокировку стабильности схемы (Sch-S) на странице Index Allocation Map (IAM) и хранить её до завершения. При попытке восстановить пространство при обычном использовании операции по уменьшению базы данных и уменьшению файлов требуют блокировки изменения схемы приSch-M перемещении или удалении страниц IAM, блокируя блокировки Sch-S , необходимые для пользовательских запросов. В результате длительные запросы могут блокировать операцию уменьшения. Это также означает, что любой новый запрос, требующий Sch-S блокировки на странице IAM, может попасть в очередь после операции уменьшения, что ещё больше усугубляет проблему параллелизма.

Введённая в SQL Server 2022 (16.x), функция ожидания при низком приоритете для операций уменьшения решает эту проблему, принимая блокировку изменения схемы на страницах IAM в WAIT_AT_LOW_PRIORITY режиме. Дополнительные сведения см. на странице WAIT_AT_LOW_PRIORITY с операциями сжатия.

Для получения дополнительной информации о Sch-S блокировках Sch-M и блокировках см. руководство по блокировке транзакций и версионированию строков.

Сжатие файла журнала

Для файлов журналов ядро СУБД использует target_size для вычисления целевого размера всего журнала. Таким образом, target_size указывает размер свободного места в журнале после операции сжатия. Затем по заданному размеру всего журнала рассчитываются заданные размеры каждого файла журнала. DBCC SHRINKFILE пытается немедленно уменьшить размер каждого физического журнала до целевого размера. Однако если часть логического журнала находится в виртуальных журналах за пределами целевого размера, ядро СУБД освобождает максимальное пространство, а затем выдает информационное сообщение. Сообщение описывает действия, которые необходимо предпринять, чтобы переместить логический журнал из виртуальных журналов в конец файла. После выполнения DBCC SHRINKFILE действий можно использовать для освобождения оставшегося пространства.

Так как файл журнала можно сжать только до границы виртуального файла журнала, сжать файл журнала до меньшего размера, чем у виртуального файла журнала, нельзя, даже если он не используется. Ядро СУБД динамически выбирает размер журнала виртуального файла при создании или расширении файлов журнала.

Рекомендации

Примите во внимание следующие сведения при планировании сжатия файла.

  • Максимальный эффект от сжатия достигается после операции, при которой создается много неиспользуемого пространства, например после усечения или удаления таблицы.

  • Большинству баз данных требуется некоторое свободное пространство для выполнения обычных ежедневных операций. Если сжатие файла базы данных производится регулярно, но размер базы данных продолжает расти, это означает, что для нормальной работы необходимо свободное пространство. В таких случаях повторное уменьшение файла базы данных контрпродуктивно. Рост файла, необходимый для выделения нового пространства после уменьшения, может снизить производительность.

  • Операция уменьшения не сохраняет фрагментационное состояние индексов в базе данных и может увеличить фрагментацию индекса, что может снизить пропускную способность чтения ввода-вывода для запросов при больших сканированиях.

  • Если нужно уменьшить файлы данных большой базы данных, рассмотрите возможность использования скрипта ShrinkDriver PowerShell. Скрипт автоматизирует и упрощает процесс уменьшения, превращая его в одну наблюдаемую и вособновляемую операцию. Скрипт сжимает несколько файлов параллельно, повторяет попытки при прерывании и выводит подробные отчёты о состоянии по мере запуска.

Устранение неполадок

В этом разделе описывается, как диагностировать и исправлять проблемы, которые могут возникнуть при выполнении DBCC SHRINKFILE команды.

Файл не сжимается

Если размер файла не меняется после безошибочной операции уменьшения, выполните следующие шаги для проверки достаточного свободного места в файле:

  • Выполните следующий запрос.

    SELECT name,
           size / 128.0 - CAST (FILEPROPERTY(name, 'SpaceUsed') AS INT) / 128.0 AS AvailableSpaceInMB
    FROM sys.database_files;
    
  • Если вы хотите уменьшить файл журнала транзакций, используйте sys.dm_db_log_space_usage режим динамического управления (DMV), чтобы увидеть пространство, используемое в журнале транзакций.

Операция уменьшения не может уменьшить размер файла при недостатке свободного пространства.

Распространённая причина, по которой файл журнала транзакций не уменьшается, — отсутствие регулярных резервных копий журналов транзакций. Чтобы усечь журнал, создайте резервную копию журнала транзакций и снова запустите операцию DBCC SHRINKFILE. Если восстановление в точке времени не требуется, рассмотрите модели восстановления (SQL Server), чтобы избежать увеличения лог-файлов.

Операция сжатия блокируется

Транзакция, запущенная под уровнем изоляции с управлением версиями строк, может блокировать операции сжатия. Например, если выполняется большая операция удаления, выполняемая под уровнем изоляции на основе версий строк, выполняется при DBCC SHRINKDATABASE выполнении операции сжатия, операция сжатия ожидает завершения удаления перед продолжением. Когда эта блокировка происходит, DBCC SHRINKFILE и DBCC SHRINKDATABASE операции печатают информационное сообщение (5202 для SHRINKDATABASE и 5203 для SHRINKFILE) в журнал ошибок SQL Server. Это сообщение регистрируется каждые 5 минут в течение первого часа, а затем по одному разу каждый час Например:

DBCC SHRINKFILE for file ID 1 is waiting for the snapshot
transaction with timestamp 15 and other snapshot transactions linked to
timestamp 15 or with timestamps older than 109 to finish.

Такое сообщение означает, что операция сжатия блокируется транзакциями с моментальным снимком, отметка времени которого старше, чем 109 (это последняя транзакция, завершенная операцией сжатия). Он также указывает transaction_sequence_numfirst_snapshot_sequence_num столбцы или столбцы в динамическом представлении управления sys.dm_tran_active_snapshot_database_transactions содержит значение 15. transaction_sequence_num Если столбец или first_snapshot_sequence_num столбец представления содержит число меньше последней завершенной транзакции операции сжатия (109), операция сжатия ожидает завершения этих транзакций.

Чтобы решить проблему, выполните один из следующих шагов:

  • Прервите выполнение транзакции, которая блокирует операцию сжатия.
  • Прервите операцию сжатия. При прерывании операции сжатия вся уже выполненная работа сохраняется.
  • Пока операция сжатия ожидает завершения блокирующей транзакции, ничего делать не нужно.

Разрешения

Необходимо быть членом предопределенной роли сервера sysadmin или предопределенной роли базы данных db_owner .

Примеры

Примеры кода в этой статье используют базу данных образца AdventureWorks2025 или AdventureWorksDW2025, которую можно скачать с домашней страницы образцов и проектов сообщества Microsoft SQL Server и.

А. Сжатие файла данных до указанного целевого размера

В приведенном ниже примере файл данных с именем DataFile1 в пользовательской базе данных UserDB сжимается до 7 МБ.

USE UserDB;
GO

DBCC SHRINKFILE (DataFile1, 7);
GO

В. Сжатие файла журнала до указанного целевого размера

В следующем примере файл журнала в базе данных AdventureWorks2025 сжимается до 1 МБ. Чтобы позволить DBCC SHRINKFILE команде уменьшить файл, его сначала усечают путём установки модели восстановления базы данных на SIMPLE.

USE AdventureWorks2025;
GO

-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks2025
    SET RECOVERY SIMPLE;
GO

-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks2025_Log, 1);
GO

-- Reset the database recovery model.
ALTER DATABASE AdventureWorks2025
    SET RECOVERY FULL;
GO

В. Усечение файла данных

В следующем примере усекается первичный файл данных в базе данных AdventureWorks2025. Выполняется запрос к представлению каталога sys.database_files для получения идентификатора файла данных file_id.

USE AdventureWorks2025;
GO

SELECT file_id,
       name
FROM sys.database_files;
GO

DBCC SHRINKFILE (1, TRUNCATEONLY);

Д. Пустой файл

Следующий пример демонстрирует процедуру очистки файла для его удаления из базы данных. Для этого примера сначала создается файл, содержащий данные.

USE AdventureWorks2025;
GO

-- Create a data file and assume it contains data.
ALTER DATABASE AdventureWorks2025
    ADD FILE (NAME = Test1data, FILENAME = 'C:\t1data.ndf', SIZE = 5 MB);
GO

-- Empty the data file.
DBCC SHRINKFILE (Test1data, EMPTYFILE);
GO

-- Remove the data file from the database.
ALTER DATABASE AdventureWorks2025
     REMOVE FILE Test1data;
GO

Е. Сжатие файла базы данных с помощью WAIT_AT_LOW_PRIORITY

В приведенном ниже примере выполняется попытка сжатия файла данных в текущей пользовательской базе данных до 1 МБ. Выполняется запрос к представлению каталога sys.database_files для получения file_id файла данных, в этом примере file_id 5. Если блокировка не может быть получена в течение одной минуты, операция сжатия прерывается.

USE AdventureWorks2025;
GO

SELECT file_id,
       name
FROM sys.database_files;
GO

DBCC SHRINKFILE (5, 1) WITH WAIT_AT_LOW_PRIORITY (ABORT_AFTER_WAIT = SELF);