diamond АШ Tlg

Ошибка реорганизации индексов MS SQL после перехода на платформу 1С 8.3.22

В платформе 8.3.22 решили побороть проблему эскалации блокировок и подкинули головняк админу. Но это только к лучшему.

TDLR (если некогда читать)

Просто отключите регламентные задания по дефрагментации и перестроению индексов - они больше не нужны.

Рекомендации Microsoft для SQL Server, нетленка начала нулевых годов

Процент фрагментации индекса Что делать
до 5% Ничего не трогать
от 5% до 30% Выполнить реорганизацию индекса: REORGANIZE
больше 30% Выполнить полное перестроение индеса: REBUILD

Существуют и другие вариации этой таблицы от экспертов, как правило в сторону понижения значений

Проблема, возникающая после обновления платформы 1С:Предприятие на версию 8.3.22

Задачи по реорганизации индексов завершаются с ошибкой:

Ошибка реорганизации индекса 1С 8.3.22

Ключевые слова: the index on table cannot be reorganized because page level locking is disabled.

Причина в том, что платформа 1С начиная с 8.3.22 теперь все индексы создаёт с настройкой, запрещающей блокировку на уровне страницы, для борьбы с эскалацией блокировок:

Новая настройка индекса 1С 8.3.22

В результате, если админ СУБД ничего не предпринял после обновления платформы 1С, то можно наблюдать такую картину, вызывающюю у него беспокойство:

Тотальная фрагментация индексов после обновления на 1С 8.3.22

Способ решения №1, самый простой

Перед задачей реорганизации индексов добавить задачу выполнения следующего скрипта на T-SQL:

USE [Infobase]
EXEC sp_MSforeachtable 'ALTER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON)' 
GO

После выполнения реорганизации необходимо вернуть настройку индексов на место:

USE [Infobase]
EXEC sp_MSforeachtable 'ALTER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = OFF)' 
GO

Способ решения №2, самый продвинутый

'Типовой' способ реорганизации индексов самый неоптимальный, т.к. он будет пытаться реорганизовать все индексы, которые превышают установленный порог дефрагментации, тогда как вместо реорганизации уже возможно требуется полное перестроение, что типично для высоконагруженных конфигураций 1С. В какой-то момент перестает хватать всей ночи чтобы успевать завершать обслуживание баз 1С к утру.

Предлагаю использовать скрипт на T-SQL, который я откуда-то давно скачал. Я его слегка модифицировал, для обхода специфики индексов на платформы 8.3.22 и новее. Скрипт имеет много настроек, сначала составляет таблицу индексов с показателем дефрагментации и затем выполняет их реорганизацию или перестроение индекса в полном соотвествии с таблицей в начале этой статьи, заодно убирает и возвращает настройку блокировки индекса обратно.

Скачать/посмотреть скрипт T-SQL

Способ решения №3, самый разумный в подавляющем большинстве случаев

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

Чаще всего ИТ-менеджеры неверно оценивают масштаб своей системы и сами присваивают себе очередное звание "HighLoad". Тут же кого-то отправляют на курсы Эксперта по технологическим вопросам 1С, начинается глубокое погружение в тему строения индексов B-tree, кластерных и некластерных, организации страниц памяти размером 8k, тонкости и стратегии обслуживания индексов - но всё это было актуально в эпоху неолита, когда трава была зелёной серверы были "bare metall", памяти мало, а базы писались на механические HDD-диски с позиционированием головок по дорожкам.

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

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