Восстановление базы данных из резервной копии кроме восстановления файлов баз данных и журнала транзакций может восстановить метаданные о настройках репликации или полнотекстового поиска, которые использовались на сервере, где резервная копия создавалась. В данной статье мы рассмотрим случай, когда восстановление из резервной копии восстановило некоторую информацию о каталоге полнотекстового поиска, что может породить ряд проблем и поэтому требует принятия администратором баз данных мер по удалению лишних и вредных в данном случае метаданных о полнотекстовом индексе и связанных с ним объектах.
Чем же может быть вредна информация о фантомном полнотекстовом индексе? Например, Вы можете столкнуться с такой ситуацией, когда изменение схемы таблицы требует удаления первичного ключа, но это сделать не удаётся, и сервер в ответ на команду:
ALTER TABLE [dbo].[ИМЯ_ТАБЛИЦЫ] DROP CONSTRAINT [ИМЯ_ИНДЕКСА];
GO
|
Выдаёт следующее сообщение об ошибке:
|
Сообщение 7613, уровень 16, состояние 1, строка 1 Cannot drop index 'ИМЯ_ИНДЕКСА' because it enforces the full-text key for table or indexed view 'ИМЯ_ТАБЛИЦЫ'. Сообщение 3727, уровень 16, состояние 0, строка 1 Could not drop constraint. See previous errors. |
В данном случае, никакого полнотекстового каталога и индексов на сервере не создавалось, а информация о том, что указанный первичный ключ является ключом полнотекстового поиска по полям этой таблицы, была привнесена в момент восстановления базы данных из резервной копии. Следует отметить, что полнотекстовый поиск мог вообще никогда не использоваться, а был настроен и потом не полностью или не правильно удалён на сервере - источнике этой резервной копии.
Первым делом, следует убедиться, что компоненты полнотекстового поиска были установлены и служба Microsoft Search запущена. Кроме того, что бы ничего не мешало Вам в работе, убедитесь в том, что для базы данных отключена опция AUTOSHRINK.
Что бы проверить, задействован ли индекс в качестве полнотекстового ключа, можно выполнить следующий запрос к метаданным сервера:
SELECT INDEXPROPERTY(OBJECT_ID('ИМЯ_ТАБЛИЦЫ'), 'ИМЯ_ИНДЕКСА', 'IsFulltextKey');
GO
|
Свойство индекса IsFulltextKey говорит о том, является ли индекс полнотекстовым ключом для указанной таблицы. Если это так, то свойство принимает значение: 1 = True. Если индекс не является полнотекстовым ключом, значение свойства равно: 0 = False. Если возвращается NULL, это говорит о том, что были указаны неверные параметры.
В нашем случае, этот запрос возвращает 1, что говорит о том, что в наших метаданных имеется фантом полнотекстового индекса.
Теперь, давайте убедимся, что установку каталога полнотекстового поиска на нашем сервере не выполняли. Для этого выполним следующую системную хранимую процедуру:
EXEC sp_help_fulltext_tables;
GO
|
Как и следовало ожидать, мы получили следующее сообщение об ошибке:
|
Сообщение 15601, уровень 16, состояние 1, процедура sp_help_fulltext_tables, строка 8 Full-Text Search is not enabled for the current database. Use sp_fulltext_database to enable Full-Text Search. The functionality to disable and enable full-text search for a database is deprecated. Please change your application. |
Что же, воспользуемся подсказкой из сообщения об ошибке и запустим на исполнение в контексте нашей базы данных следующий код:
EXEC sp_fulltext_database 'enable';
GO
|
Теперь, когда включение полнотекстового поиска для нащшей базы данных состоялось успешно, давайте снова выполним:
EXEC sp_help_fulltext_tables;
GO
|
На этот раз, мы получили ожидаемую информацию о задействованных в полнотекстовом поиске таблицах. В полученной таблице видно, кто владелец таблицы, имя таблицы, имя ключа полнотекстового индекса, номер по порядку поля ключа в таблице, является ли этот индекс активным и имя полнотекстового каталога.
Стандартный путь удаления привязки поля таблицы и самой таблицы к каталогу полнотекстового поиска сводиться к вызову двух процедур:
EXEC dbo.sp_fulltext_column @tabname = N'[dbo].[ИМЯ_ТАБЛИЦЫ]',
@colname = N'ИМЯ_ИСПОЛЬЗУЕМОГО_ПОЛЯ',
@action = N'drop'
GO
|
Что эквивалентно:
ALTER FULLTEXT INDEX ON [dbo].[ИМЯ_ТАБЛИЦЫ]
DROP (ИМЯ_ИСПОЛЬЗУЕМОГО_ПОЛЯ)
GO
|
А после того, как будут отключены все задействованные в полнотекстовых индексах поля таблицы, деактивировать в полнотекстовом поиске и саму таблицу:
EXEC dbo.sp_fulltext_table @tabname = N'[dbo].[ИМЯ_ТАБЛИЦЫ]',
@action = N'deactivate'
GO
|
Что эквивалентно:
DROP FULLTEXT INDEX ON [dbo].[ИМЯ_ТАБЛИЦЫ]
GO
|
Теперь, запуск:
EXEC sp_help_fulltext_tables;
GO
|
...не возвращает записей о таблице, метаданные об использовании которой в полнотекстовом поиске мы хотели удалить.
Ну и напоследок, если каталог полнотекстового индекса больше ни для чего не нужен, его тоже можно удалить:
DROP FULLTEXT CATALOG [ИМЯ_КАТАЛОГА_ПОЛНОТЕКСТОВОГО_ПОИСКА]
GO
|
Дополнительная информация: Хранимая процедура sp_fulltext_table, на самом деле, вносит изменения в системную таблицу sysobjects, поразрядно прибавляя или вычитая шестнадцатеричное число 189 к полю status, а в поле ftcatid размещается идентификатор каталога полнотекстового поиска. Кроме того, изменяется поле colstat (оно было = 16) соответствующей записи в системной таблице syscolumns. ИСТОЧНИК
