Поделиться через


DBCC SHRINKDATABASE (Transact-SQL)

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

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

Синтаксис

DBCC SHRINKDATABASE 
( database_name | database_id | 0 
     [ , target_percent ] 
     [ , { NOTRUNCATE | TRUNCATEONLY } ] 
)
[ WITH NO_INFOMSGS ]

Аргументы

  • database_name | database_id | 0
    Имя или идентификатор базы данных, которая должна быть сжата. Если указано значение 0, используется текущая база данных.

  • target_percent
    Процент свободного пространства, которое должно остаться в базе данных после сжатия.

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

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

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

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

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

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

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

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

Имя столбца

Описание

DbId

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

FileId

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

CurrentSize

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

MinimumSize

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

UsedPages

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

EstimatedPages

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

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

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

Замечания

Чтобы сжать все файлы данных и журналов указанной базы данных, выполните команду DBCC SHRINKDATABASE. Чтобы сжать один файл данных или файл журнала в указанной базе данных, выполните команду DBCC SHRINKFILE.

Чтобы просмотреть количество свободного (нераспределенного) пространства в базе данных выполните процедуру sp_spaceused.

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

Размер базы данных нельзя сделать меньше минимального размера базы данных. Минимальный размер — это размер, указанный при создании базы данных, или последний размер, явно установленный операцией изменения размера файла, такой как DBCC SHRINKFILE или ALTER DATABASE. Например, если база данных была создана с размером 10 МБ и потом увеличилась до 100 МБ, ее можно сжать только до 10 МБ, даже если все данные удалены из базы данных.

Выполнение операции DBCC SHRINKDATABASE без указания параметра NOTRUNCATE или TRUNCATEONLY равносильно выполнению операции DBCC SHRINKDATABASE с параметром NOTRUNCATE после выполнения операции DBCC SHRINKDATABASE с параметром TRUNCATEONLY.

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

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

Работа команды DBCC SHRINKDATABASE

Инструкция DBCC SHRINKDATABASE сжимает файлы данных по одному, а файлы журнала так, как будто все они представляют один непрерывный пул журнала. Сжатие файлов всегда ведется с конца.

Предположим, что существует база данных с именем mydb, имеющая один файл данных и два файла журнала. Каждый файл данных и журнала имеет размер 10 МБ, а файл данных содержит 6 МБ данных.

Компонент Database Engine вычисляет целевой размер каждого файла. Это размер, до которого файл данных должен быть сжат. Если инструкция DBCC SHRINKDATABASE указана с аргументом target_percent, то компонент Database Engine вычисляет целевой размер таким образом, чтобы в файле после сжатия было target_percent процентов свободного пространства. Например, если указать аргумент target_percent со значением 25 для сжатия базы данных mydb, компонент Database Engine рассчитает целевой размер для файла 8 МБ (6 МБ данных и 2 МБ свободного пространства). Поэтому компонент Database Engine перемещает все данные из последних 2 МБ файла данных в любое свободное пространство в первых 8 МБ файла данных, а затем сжимает файл.

Предположим, что файл данных базы данных mydb содержит 7 МБ данных. При указании аргумента target_percent со значением 30 допускается сжатие данного файла для освобождения 30 процентов пространства. Однако при указании аргумента target_percent со значением 40 файл данных сжат не будет, потому что компонент Database Engine не может сжать файл до меньшего размера, чем текущий размер занимаемых данных. Данную ситуацию можно представить и другим способом: 40 процентов желаемого свободного пространства + 70 процентов от полного файла данных (7 МБ из 10 МБ) больше, чем 100 процентов. Так как сумма желаемого освобождаемого процента и текущего процента, занимаемого файлом данных, превосходит 100 (на 10 процентов), любое значение target_percent, которое больше 30, не приведет к сжатию файла данных.

Для файла журнала компонент Database Engine использует аргумент target_percent для вычисления целевого размера всего журнала. Поэтому аргумент target_percent является количеством свободного пространства в журнале после операции сжатия. Целевой размер всего журнала затем пересчитывается в целевой размер каждого файла журнала.

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

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

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

Обратите внимание на следующие сведения при планировании сжатия базы данных.

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

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

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

  • Не следует устанавливать параметр базы данных AUTO_SHRINK в значение ON без достаточных на то оснований.

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

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

DBCC SHRINKDATABASE for database ID 9 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.

Примеры

А. Сжатие базы данных и определение количества свободного пространства в процентах

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

DBCC SHRINKDATABASE (UserDB, 10);
GO

Б. Усечение базы данных

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

DBCC SHRINKDATABASE (AdventureWorks, TRUNCATEONLY);