SQL Server: как сжать файлы FileStream?
Для проекта я использую SQL Server 2008 R2. Одна таблица имеет столбец файлового потока.
Я сделал несколько нагрузочных тестов, и теперь в базе данных используется ~20 ГБ.
У меня есть пустые таблицы, кроме нескольких (таблицы конфигурации). Но моя база данных все еще занимала много места. Так что я использовал Task -> Shrink -> Database / Files
Но моя база данных все еще использует что-то вроде 16 ГБ.
Я обнаружил, что файл filestream все еще занимает много места.
Проблема в том, что мне нужно сделать резервную копию этой базы данных, чтобы экспортировать ее на конечный рабочий сервер, и, если я укажу на сжатие резервной копии, я получу файл больше, чем 3.5Go. Не удобно хранить и загружать.
И я планирую гораздо больший тест, поэтому я хочу знать, как уменьшить это пустое пространство.
Когда я пытаюсь:
Я получаю это исключение:
The properties SIZE, MAXSIZE, or FILEGROWTH cannot be specified for the FILESTREAM data
file 'FileStreamFile'. (Microsoft SQL Server, Error: 5509)
И что же мне делать?
Я нашел несколько тем с этой ошибкой, но они касались удаления столбца filestream.
2 ответа
Старые версии файлов удаляются из файлового потока через процесс сбора мусора, который выполняется во время процесса проверки.
см. http://sqlskills.com/BLOGS/PAUL/post/FILESTREAM-garbage-collection.aspx для полного объяснения.
Итак - вы перепрыгиваете через все обручи, запускаете резервное копирование журнала, контрольную точку и затем... ждете, потому что глупый сборщик мусора, похоже, удаляет файлы только со скоростью примерно 4 или 5 в секунду.
новинка 2012 года, я думаю? является sp_filestream_force_garbage_collection ( http://msdn.microsoft.com/en-us/library/gg492195.aspx) - но я не использовал его, поэтому не могу сказать, насколько он эффективен.
Проблема в том, что пространство не освободится, пока не будет завершена сборка мусора. К сожалению, нет способа заставить это.
Я использовал скрипт powershell для перебора файловых потоков и очистки их содержимого. (обратите внимание, что это удалит данные файлового потока из всех записей, если вам это не нужно). Это оставит файл, связанный с записью, на месте, но будет выглядеть, как поле было пустым.
Вам нужно будет изменить путь к папке с файловой командой, но это по сути то, что я использовал.
$files = Get-ChildItem -Path "C:\MSSQL\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\MyDbRestore_9.MyDbRestore_Filestream" -Recurse -File -Exclude "*.hdr"
ForEach ($file in $files) { Clear-Content $file.FullName }