У меня есть несколько таблиц с количеством строк от 5M до 1,5G
У каждой таблицы есть поле BLOB, размер которого варьируется от 100 байт до 30 мегабайт и который хранится в виде «типов больших значений вне строки» = ON
Таблицы хранятся в разных файловых группах по 3-4 файла на каждом диске @ разные LUNs @ очень быстрое SAN
Каждый день эти таблицы увеличиваются до 5-100 ГБ в размерах и 600К - 1,5М строк
По истечении определенного промежутка времени , который варьируется от 2 недель до 6 месяцев, некоторые строки удаляются или перемещаются в архивную БД, поэтому в рабочих таблицах старше 6 месяцев нет строк.
Текущая конфигурация сервера:
- Ядро SQL-сервера 2008 R2 SP1 Enterprise, 24 ядра, 64 ГБ ОЗУ
- SQL Server работает с дополнительными флагами запуска:
-Т 3640; (Устраняет отправку сообщений DONE_IN_PROC клиенту для каждого оператора в хранимой процедуре. Это похоже на настройку сеанса SET NOCOUNT ON, но при установке в качестве флага трассировки каждый сеанс клиента обрабатывается таким образом)
-T 1118; (переключает выделения в tempDB с 1pg за раз (для первых 8 страниц) на один экстент.)
-T 2301; (Включает расширенную оптимизацию, специфичную для запросов поддержки принятия решений. Этот параметр применяется к обработке поддержки принятия решений больших наборов данных)
-T 1117; (Увеличивает все файлы данных одновременно, иначе он идет по очереди.)
-E; (Увеличивает количество экстентов, которые выделяются для каждого файла в файловой группе. Этот параметр может быть полезен для приложений хранилища данных, у которых ограниченное число пользователей, выполняющих индекс или сканирование данных)
-T 834; (Заставляет SQL Server использовать выделения больших страниц Windows для памяти, выделенной для пула буферов, http://msdn2.microsoft.com/en-us/library/aa366720.aspx , http://support.microsoft. com / kb / 920093 )
- SQL Server использует большие страницы
- SQL Server использует опцию быстрой инициализации файла
- AUTOSHRINK выключен для всех баз данных
Проблема в том, что, начиная с некоторой точки времени работы сервера (от пары дней до месяцев), GHOST CLEANUP
процесс отказывается от принудительной очистки и просто выполняет свою обычную работу - очищает несколько страниц за несколько секунд ( which is seen thru Extended Events
), что не подходит , потому что он не может очистить все удаленные строки
Проблема сохраняется со времен SQL Server 2005 RTM Enterprise
Как я пытался решить проблему:
- Пытался форсировать операции SCAN над кластерными индексами таблиц.
- Попытался принудительно выполнить операции SCAN, которые включают все содержимое столбца BLOB в кластеризованных индексах таблиц.
- system sp_clean_db_free_space & sp_clean_db_file_free_space
- вручную dbcc cleanpage (@dbid, @fileid, @page) для всех файлов и страниц в БД
- кластерный индекс перестраивает и реорганизует
- воссоздание базы данных
DBCC FORCEGHOSTCLEANUP
Когда я запускаю запрос:
select * from sys.dm_db_index_physical_stats(db_id(), object_id('ProblemTable'), 1, 0, 'detailed')
Я вижу миллионы и десятки миллионов фиктивных записей, но только для типа единицы выделения LOB_DATA
Единственное, что помогает:
- остановка сервера с помощью команды SHUTDOWN или перезапуск всего хоста - это помогает, после перезапуска процесс GHOST CLEANUP выполняется несколько часов и фактически очищает все скрытые записи
- DBCC SHRINKFILE с опцией EMPTYFILE - перемещение всех данных из одного файла в другой или только что созданные файлы очищает только записи-призраки в этом файле - проблема в том, что я действительно ненавижу операции сжатия. И это занимает 3-4 дня для одного файла
вопрос - существует ли какой-либо программный (предпочтительный) или обслуживающий способ заставить GHOST CLEANUP вообще без простоя сервера, потому что время простоя сервера стоит слишком дорого, даже недопустимо - от тысяч до десятков тысяч долларов в час
Проблемы были замечены так же, как мои здесь:
- http://support.microsoft.com/kb/932115
- http://www.sqlservercentral.com/Forums/Topic496244-149-1.aspx
И то же самое здесь: