Как исправить ошибку взаимоблокировки MS SQL Server -1073548784 при обслуживании индексов?

Системный администратор IT и автоматизация бизнеса
← На главную

При выполнении ночного плана обслуживания базы данных MS SQL Server (Maintenance Plan) может возникать сбой с кодом ошибки -1073548784. В тексте ошибки указывается, что транзакция перестройки или обслуживания индекса (команда ALTER INDEX) стала жертвой взаимоблокировки (deadlock) с другим процессом СУБД. В результате обслуживание таблицы прерывается.

Проанализируем причины возникновения этой проблемы и разберем по шагам, как настроить регламентные процедуры платформы 1С и MS SQL Server для исключения подобных конфликтов.

Выясним причину возникновения ошибки

Код ошибки -1073548784 является универсальным кодом сбоя подсистемы SSIS при выполнении T-SQL задач в планах обслуживания. Само сообщение «Транзакция вызвала взаимоблокировку ресурсов блокировка с другим процессом и стала жертвой взаимоблокировки» говорит о том, что два или более процесса заблокировали ресурсы в противоположном порядке.

Рассмотрим основные факторы, приводящие к взаимоблокировке при обслуживании индексов:

  1. Пересечение с фоновыми и регламентными заданиями 1С: Даже если пользователи ночью не работают в программе, платформа 1С может выполнять автоматические фоновые задачи (расчет итогов, обновление полнотекстового поиска, обработка очередей, интеграционные обмены). Если 1С запрашивает блокировку стабильности схемы Sch-S, а SQL Server пытается выполнить ALTER INDEX REBUILD с захватом монопольной блокировки схемы Sch-M, возникает конфликт.
  2. Параллельное обслуживание в нескольких потоках: Запуск нескольких шагов обслуживания или нескольких планов обслуживания одновременно может привести к тому, что операции над разными индексами одной таблицы или смежных таблиц заблокируют друг друга.
  3. Низкий приоритет операции обслуживания: По умолчанию сессии имеют одинаковый приоритет DEADLOCK_PRIORITY NORMAL. При возникновении циклической блокировки SQL Server выбирает жертвой тот процесс, откат которого требует наименьших ресурсов. Откат начавшейся перестройки индекса часто оказывается менее затратным, чем откат транзакции записи 1С, поэтому СУБД завершает именно задание обслуживания.

Шаг 1. Настройка завершения сеансов и отключение регламентных заданий 1С

Для гарантированного предотвращения конфликтов необходимо развести по времени или полностью приостанавливать фоновые процессы 1С на период проведения обслуживающих процедур SQL Server.

Разберем основные действия:

  1. Блокировка установки соединений: В консоли администрирования серверов 1С:Предприятие или через свойства информационной базы в режиме конфигуратора установите блокировку начала сеансов работы с базой данных на время обслуживания.
  2. Отключение регламентных заданий: В свойствах информационной базы установите флаг Блокировка регламентных заданий включена. Это предотвратит автоматический запуск фоновых задач 1С во время перестройки индексов.
  3. Завершение фоновых сеансов: Убедитесь, что перед началом обслуживания все фоновые задания 1С завершили свою работу и не удерживают транзакции в базе данных.

Шаг 2. Оптимизация потоков выполнения в планах обслуживания

Если обслуживание настроено через стандартный мастер Maintenance Plan Wizard в SQL Server Management Studio (SSMS), убедитесь в последовательном выполнении задач:

  1. Настройте выполнение задач обслуживания строго в один поток (однопоследовательное выполнение задач вместо параллельного).
  2. Не запускайте одновременно операции резервного копирования, обновления статистики и перестройки индексов для одной и той же базы данных.

Шаг 3. Использование T-SQL скриптов с параметрами предотвращения блокировок

Стандартные планы обслуживания SSMS имеют ограниченные возможности обработки ошибок. Для более гибкого управления обслуживанием рекомендуется использовать T-SQL скрипты с явным указанием параметров ожидания блокировок и уровня параллелизма.

Посмотрим на пример команды с ограничением степени параллелизма MAXDOP = 1, что снижает вероятность внутренних межпоточных блокировок:


ALTER INDEX [_InfoRg8163_ByDims8181_RRNR] ON [dbo].[_InfoRg8163]
REBUILD WITH (
    FILLFACTOR = 80,
    MAXDOP = 1
);

Для SQL Server версии 2014 и выше при наличии редакции Enterprise можно использовать параметр WAIT_AT_LOW_PRIORITY. Данный параметр позволяет процессу обслуживания ждать снятия блокировок с низким приоритетом и автоматически завершать блокирующие сессии или саму процедуру переиндексации по истечении таймаута:


ALTER INDEX [_InfoRg8163_ByDims8181_RRNR] ON [dbo].[_InfoRg8163]
REBUILD WITH (
    ONLINE = ON (
        WAIT_AT_LOW_PRIORITY (
            MAX_DURATION = 5 MINUTES,
            ABORT_AFTER_WAIT = SELF
        )
    )
);

Шаг 4. Диагностика взаимоблокировок

Чтобы точно определить, какой именно процесс вступает в конфликт с операцией ALTER INDEX, проанализируем блокировки с помощью системных средств СУБД или 1С:

  1. Технологический журнал 1С: Настройте сбор событий TLOCK и TDEADLOCK в файле logcfg.xml для фиксации конфликтов на стороне платформы 1С.
  2. Расширенные события MS SQL (Extended Events): Создайте сессию Extended Events с перехватом события xml_deadlock_report. Это позволит получить подробный граф взаимоблокировки (Deadlock Graph) с текстом обоих запросов и участниками конфликта.
  3. Флаги трассировки: Включите флаги трассировки 1204 и 1222 в SQL Server для записи подробной информации о взаимоблокировках в журнал ошибок SQL Server Error Log.
← На главную