Уменьшите базу данных ниже ее первоначального размера

10

У меня есть база данных разработчика SQL Server 2005, которая является 30-гигабайтной копией live. Мы удалили некоторые данные, которые не нужны в dev, что приводит к уменьшению занимаемого файлового пространства до 20 ГБ. Таким образом, у нас есть около 33% неиспользованных.

Мне нужно освободить место, которое позволит нам иметь на сервере вторую БД разработчика (в зависимости от урезанной версии); однако, я не могу вернуть себе место, я сделал следующее:

  • Начальный размер файла SMS2_Dataсоставляет 30 ГБ.

    DBCC SHRINKFILE (N'SMS2_Data' , 0, TRUNCATEONLY)

    с последующим

    DBCC SHRINKFILE (N'SMS2_Data' , 19500)

Нет радости Я попытался сделать резервную копию, создать новую БД с небольшим начальным размером, а затем восстановить, без удовольствия, так как начальный размер перезаписывается. Также попробовал:

ALTER DATABASE SMS2HazSub MODIFY FILE (NAME = 'SMS2_Data', SIZE = 20000) 

Это ошибочно, сказав:

ИЗМЕНИТЬ ФАЙЛ не удалось. Указанный размер меньше текущего размера.

Я попытался 20800, а затем продолжал идти до 29000 (29 ГБ), и это все еще не позволит мне изменить его.

Сделали усадочной затем изменил режим восстановления с FULLк SIMPLEи обратно. Нет радости

Я думал, что это было связано с некоторыми TEXTобластями. У нас есть около 6 по всей системе. Так что в качестве теста я отбросил их все, а затем сделал сжатие файла и до сих пор без изменений.

Единственный оставленный вариант - повторно импортировать данные в другую БД. Это не практично, так как это должно быть сделано в реальной базе данных, которая несет слишком большой риск. Мы регулярно собираем копию действующей БД и перезаписываем dev / test. У нас есть что-то вроде 500 столов. Я хотел бы сделать это, не рискуя экспортировать данные в новую БД.

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

Сервер находится в режиме совместимости 90, но это SP2. Теперь я сделал 3 раза: переиндексировать все таблицы, создать резервную копию базы данных, сжать файл, сжать базу данных. Все еще нет радости.

EXECUTE sp_spaceused возвращает:

database_name   database_size   unallocated space
SMS2Tests       31453.94 MB     13903.16 MB

reserved     data         index_size   unused
16545568 KB  10602264 KB  4254360 KB   1688944 KB
Пол Уайт 9
источник

Ответы:

3

Как уже упоминали некоторые люди, вы можете создать новую базу данных и «скопировать» материал из старой базы данных. Это будет лучшим вариантом для вас. Однако я заметил, что вы хотите делать это довольно регулярно. Таким образом, ваш лучший вариант - Redgate Data Compare и Redgate Compare . Оба являются частью пакета Redgate SqlToolbelt .

Так, что вы делаете:

  1. Создайте пустую БД с небольшим начальным размером.
  2. Используйте Redgate Compare для копирования структуры БД, функций и т. Д. Из старого БД
  3. Используйте Redgate Data Compare для копирования данных из старой базы данных в новую.
  4. Вы работаете с базой данных разработчиков, а затем в любое время либо просто сравниваете данные, и регулярно обновляете базу данных разработчиков, либо, если вы вносите какие-либо изменения в базу данных, вы можете развернуть эти изменения с помощью Redgate Compare, а затем выполнить Redgate Data Compare.

Что хорошо в Data Compare, так это то, что после того, как вы скопируете эти 30 ГБ данных (вы можете сделать это, начиная только с нескольких таблиц), через некоторое время ему просто нужно «перекомпилировать» только некоторые изменения, а не целые 30 ГБ данных. Это означает, что он окажет гораздо меньшее влияние на обе базы данных, чем при обычном копировании.

Сумасшедший мальчик
источник
2

Несколько возможностей здесь.

Прежде всего, вы на SQL 2005 SP3 или более поздней версии? Некоторые сообщали о проблемах с SHRINKFILE в предыдущих версиях (см. Http://www.sqlservercentral.com/Forums/Topic981292-146-6.aspx#bm985164 )

Во-вторых, можете ли вы убедиться, что для базы данных установлен режим совместимости 90, а не режим 80? Это, очевидно, было проблемой с SQL 2000, но ограничение было снято в SQL 2005. Если ваша база данных по-прежнему настроена на совместимость с режимом 80, это все еще может быть проблемой.

В-третьих, это может быть проблемой с данными больших объектов (text, ntext, varchar (max)). Смотрите отличную статью Пола Рэндалла здесь

Я предполагаю, что вы понимаете, что на самом деле делает SHRINKing, и что это может негативно повлиять на вашу производительность:

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

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

Если вы посмотрите на свой сокращенный SPID в мониторе активности, похоже, он что-то делает? (Счетчики ввода-вывода и ЦП меняются) Или он заблокирован? Единственное, о чем я могу думать, - это если в базе данных есть другие действия, блокирующие сжатие. Убедитесь, что другие активные спиды не используют базу данных в то время.

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

BradC
источник
1

SHRINKDATABASE только уменьшит базу данных (в лучшем случае) до минимального размера, так что это вам не поможет.

Когда вы пытаетесь сжать ФАЙЛ через пользовательский интерфейс SSMS, используя значения по умолчанию, он использует 'DBCC SHRINKFILE (N'MyDB', 0, TRUNCATEONLY) '. Эта команда только уменьшит файл (в лучшем случае) до последней выделенной степени.

Если вы хотите сжать файл ниже MinSize, просто измените параметр DBCC SHRINKFILEс 0 на размер, до которого вы хотите попытаться сжать файл в МБ. Ненулевое число скажет SHRINKFILE уменьшить файл до этого размера, если это возможно. Так DBCC SHRINKFILE('MyDB', 300, TRUNCATEONLY)что сократит файл до 300 МБ, если в базе данных есть место.

Вы можете увидеть MinSize, запустив это:

DBCC TRACEON(3604)
go
DBCC PAGE('MyDB', 1, 0, 3) with tableresults
go

MinSize в МБ рассчитывается следующим образом: (MinSize * 8) / 1024

infoone
источник
0

Если вы действительно хотите сделать это:

  • установить режим восстановления на простой
  • быть осведомленным: DBCC SHRINKDATABASE (MyDatabase, TRUNCATEONLY);
p.campbell
источник
0

Если у вас есть, скажем, 20003 (МБ) фактических данных в базе данных, то «SIZE = 20000» будет слишком маленьким. Попробуйте с 21000 или 25000, посмотрите, работает ли это. (И помните, 1 ГБ = 1024 МБ.)

Филип Келли
источник
0

Пытаться

DBCC SHRINKDATABASE (N'SMS2_Data' , 0)

Я использовал это в имеющейся у меня базе данных SQL 2005, и выделенное пространство для файла данных изменилось с 10,2 ГБ до 3 ГБ.

Кстати, это длительный процесс, и он занял чуть более 19 минут для моей базы данных.


источник
ps Только что проверил, и Модель восстановления для моей базы данных установлена ​​на Простой.
Это не имело никакого значения, я уверен, что это то же самое, что делается через интерфейс.
0

Я предполагаю, что у вас есть один файл базы данных с логическим именем SMS2_Data. У вас также есть один или несколько файлов журнала транзакций в базе данных.

У вас есть проблема, которую нельзя исправить в текущей копии базы данных. Важная информация, которую вы заявляете, заключается в том, что «исходный размер файла базы данных составляет 30 ГБ». К сожалению, этот файл нельзя сжать меньше, чем его первоначальный размер.

Как вы уже испытали, SHRINKDB и SHRINKFILE не дают вам то, что вы хотите. Эти команды следуют правилу уменьшения не меньше, чем правило оригинального размера. Таким образом, вы можете только уменьшить базу данных до исходного размера, а не меньше.

Резервное копирование и восстановление базы данных в существующую меньшую базу данных также не работает. Когда вы выполняете восстановление базы данных, файлы базы данных восстанавливаются до размеров файлов, которые были во время резервного копирования. И модель восстановления (простая, полная и т. Д.) Не имеет отношения к этой проблеме.

И последний пункт плохих новостей. Вы можете добавить другие файлы базы данных меньшего размера в базу данных, перенести все данные из файла размером 30 ГБ и затем удалить его. К сожалению, это тоже не сработает, потому что вы не можете удалить исходный файл из базы данных.

Итак, лучшее решение - скопировать данные в другую базу данных. У вас есть несколько вариантов здесь, и, возможно, вы уже знаете о них. Первым шагом является создание новой базы данных, размер которой меньше размера данных. Затем вы можете расширить размер базы данных до необходимого размера.

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

  1. Создать новую базу данных меньшего размера, чем исходная база
  2. Установите пакет служб SSIS с задачей передачи базы данных. Поставьте задачу использовать онлайн-перевод.
  3. Запустите пакет служб SSIS.
  4. Пакет служб SSIS может изменить размер базы данных в соответствии с размером исходной базы данных. Сократите эту базу данных, потому что она имеет меньший исходный размер файла.

Дополнительная информация о задаче передачи базы данных служб SSIS .

качается
источник
0

Некоторое неиспользуемое пространство в базе данных является нормальным.
Если у вас много больших записей (скажем, длинных строк), на страницах данных может быть много неиспользуемого пространства (поскольку одна запись обычно не разделяется между страницами).
Другое дело, что фактор заполнения - изначально кластерные индексы не создаются на 100% заполненными, чтобы избежать разбиения страниц (дорогая операция) при последующих вставках.
Если из базы данных было удалено много данных, пространство, ранее занимаемое этими данными, не будет автоматически возвращено - оно останется выделенным для таблицы.

Попробуйте вызвать DBCC DBREINDEX (table_name, '', 100)каждую таблицу в вашей базе данных - она ​​перестроит все индексы с коэффициентом заполнения 100%, чтобы данные располагались как можно более компактно. Затем попробуйте снова сжать базу данных.

VladV
источник
0

Я обнаружил, что сокращение базы данных SQL Server может быть проблематичным. Такое чувство, что ты должен сделать песню и танец рутины.

Это процесс, который я обычно прохожу:

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

Мне пришлось проделать этот процесс несколько раз, до трех раз, чтобы он наконец заработал. У нас была база данных размером более 68 ГБ с 98% неиспользуемого пространства. Несколько раз проходил через эту песню и танец, но в итоге он сократился до 1 ГБ.


источник
0

Я бы попытался уменьшить первоначальный размер mdf-файла до 29 000 МБ, а затем до 28 000, обнаруживая близкое попадание.

Неразумно ожидать уменьшения размера файла базы данных на 30% путем удаления 30% данных.

Вы можете оценить, сколько неиспользуемого пространства в вашей базе данных,

execute sp_spaceused

в контексте вашей базы данных (используйте yourdatabaename;)
Можете ли вы опубликовать результат ее выполнения?


Обновление:
я отправил свой связанный вопрос на этом:

Геннадий Ванин Геннадий Ванин
источник
Это не сработало слишком хорошо. 13903,16мб свободного пространства. Неиспользованный индекс 1688944 КБ