При выполнении ночного плана обслуживания базы данных MS SQL Server (Maintenance Plan) может возникать сбой с кодом ошибки -1073548784. В тексте ошибки указывается, что транзакция перестройки или обслуживания индекса (команда ALTER INDEX) стала жертвой взаимоблокировки (deadlock) с другим процессом СУБД. В результате обслуживание таблицы прерывается.
Проанализируем причины возникновения этой проблемы и разберем по шагам, как настроить регламентные процедуры платформы 1С и MS SQL Server для исключения подобных конфликтов.
Код ошибки -1073548784 является универсальным кодом сбоя подсистемы SSIS при выполнении T-SQL задач в планах обслуживания. Само сообщение «Транзакция вызвала взаимоблокировку ресурсов блокировка с другим процессом и стала жертвой взаимоблокировки» говорит о том, что два или более процесса заблокировали ресурсы в противоположном порядке.
Рассмотрим основные факторы, приводящие к взаимоблокировке при обслуживании индексов:
Sch-S, а SQL Server пытается выполнить ALTER INDEX REBUILD с захватом монопольной блокировки схемы Sch-M, возникает конфликт.DEADLOCK_PRIORITY NORMAL. При возникновении циклической блокировки SQL Server выбирает жертвой тот процесс, откат которого требует наименьших ресурсов. Откат начавшейся перестройки индекса часто оказывается менее затратным, чем откат транзакции записи 1С, поэтому СУБД завершает именно задание обслуживания.Для гарантированного предотвращения конфликтов необходимо развести по времени или полностью приостанавливать фоновые процессы 1С на период проведения обслуживающих процедур SQL Server.
Разберем основные действия:
Если обслуживание настроено через стандартный мастер Maintenance Plan Wizard в SQL Server Management Studio (SSMS), убедитесь в последовательном выполнении задач:
Стандартные планы обслуживания 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
)
)
);
Чтобы точно определить, какой именно процесс вступает в конфликт с операцией ALTER INDEX, проанализируем блокировки с помощью системных средств СУБД или 1С:
TLOCK и TDEADLOCK в файле logcfg.xml для фиксации конфликтов на стороне платформы 1С.xml_deadlock_report. Это позволит получить подробный граф взаимоблокировки (Deadlock Graph) с текстом обоих запросов и участниками конфликта.1204 и 1222 в SQL Server для записи подробной информации о взаимоблокировках в журнал ошибок SQL Server Error Log.