DBCC SHRINKFILE (Transact-SQL)

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

Значок ссылки на разделСинтаксические обозначения в Transact-SQL

Синтаксис

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

Аргументы

  • file_name
    Логическое имя файла, предназначенного для сжатия.

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

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

    ПримечаниеПримечание

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

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

  • EMPTYFILE
    Выполняет миграцию всех данных из указанного файла в другие файлы в той же файловой группе. Поскольку компонент Database Engine больше не разрешает размещать данные в пустом файле, этот файл может быть удален инструкцией ALTER DATABASE.

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

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

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

    Аргумент target_size не обрабатывается, если указан аргумент TRUNCATEONLY.

    Аргумент TRUNCATEONLY применим только к файлам данных.

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

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

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

Имя столбца

Описание

DbId

Идентификатор базы данных, файл которой компонент Database Engine пытался сжать.

FileId

Идентификационный номер файла, сжатие которого было предпринято компонентом Database Engine.

CurrentSize

Количество 8-килобайтных страниц, занятых файлом в настоящее время.

MinimumSize

Минимальное количество 8-килобайтных страниц, которое может занимать файл. Оно соответствует минимальному размеру или размеру файла, указанному при создании.

UsedPages

Количество 8-килобайтных страниц, используемых файлом в настоящее время.

EstimatedPages

Количество 8-килобайтных страниц, до которого можно было бы сжать файл по оценке компонента Database Engine.

Замечания

Инструкция DBCC SHRINKFILE применяется к файлам в текущей базе данных. Дополнительные сведения об изменении текущей базы данных см. в разделе USE (Transact-SQL).

Операции DBCC SHRINKFILE могут быть остановлены на любом этапе процесса, при этом вся выполненная работа сохраняется.

В случае сбоя операции DBCC SHRINKFILE возникает ошибка.

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

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

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

Так как файл журнала может быть сжат только до границы виртуального файла журнала, сжатие файла журнала к размеру, меньшему, чем размер виртуального файла журнала, невозможно, даже если он не используется. Размер виртуального файла журнала динамически выбирается компонентом Database Engine при создании или расширении файлов журнала. Дополнительные сведения о виртуальных файлах журнала см. в разделе Физическая архитектура журнала транзакций.

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

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

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

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

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

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

Этот раздел описывает методы диагностики и устранения проблем, которые могут произойти при выполнении команды DBCC SHRINKFILE:

Файл не удалось сжать

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

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

    SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
    FROM sys.database_files;
    
  • Выполните команду DBCC SQLPERF, чтобы освободить пространство, используемое журналом транзакций.

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

Обычно это файл журнала, который сжимается незначительно. Это характерно для файла журнала, который не может быть усечен. Можно усечь файл журнала, установив значение SIMPLE для модели восстановления базы данных или создав резервную копию журнала, а затем выполнив операцию DBCC SHRINKFILE снова. Дополнительные сведения см. в разделах Усечение журнала транзакций и Сжатие журнала транзакций.

Операция сжатия заблокирована

Операции сжатия могут быть блокированы транзакцией, запущенной с уровнем изоляции, основанном на управлении версиями строк. Например, если при выполнении масштабной операции удаления с уровнем изоляции, основанном на управлении версиями строк, выполнить инструкцию DBCC SHRINK DATABASE, то, прежде чем приступить к сжатию файлов, она будет ожидать завершения операции удаления. В этом случае операции 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_num или first_snapshot_sequence_num в динамическом представлении управления sys.dm_tran_active_snapshot_database_transactions содержат значение 15. Если столбцы transaction_sequence_num или first_snapshot_sequence_num в представлении содержат меньшее число, чем последняя транзакция, выполненная операцией сжатия (109), то операция сжатия будет ждать завершения этих транзакций.

Разрешить эту проблему можно одним из следующих способов.

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

  • Прервите операцию сжатия. Если операция сжатия прервана, любая завершенная работа сохранена.

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

Дополнительные сведения о журнале ошибок SQL Server см. в разделе Просмотр журнала ошибок SQL Server.

Разрешения

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

Примеры

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

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

USE UserDB;
GO
DBCC SHRINKFILE (DataFile1, 7);
GO

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

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

USE AdventureWorks2008R2;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks2008R2_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY FULL;
GO

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

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

USE AdventureWorks2008R2;
GO
SELECT file_id, name
FROM sys.database_files;
GO
DBCC SHRINKFILE (1, TRUNCATEONLY);

Г. Освобождение файла

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

USE AdventureWorks2008R2;
GO
-- Create a data file and assume it contains data.
ALTER DATABASE AdventureWorks2008R2 
ADD FILE (
    NAME = Test1data,
    FILENAME = 'C:\t1data.ndf',
    SIZE = 5MB
    );
GO
-- Empty the data file.
DBCC SHRINKFILE (Test1data, EMPTYFILE);
GO
-- Remove the data file from the database.
ALTER DATABASE AdventureWorks2008R2
REMOVE FILE Test1data;
GO