После обновления конфигураций на платформе 1С:Предприятие 8.3 (особенно тяжелых решений, таких как «Управление торговлей», «Комплексная автоматизация» или «ERP») администраторы и разработчики часто сталкиваются со сбоями в работе распределенных информационных баз (РИБ). Типичный сценарий: обновление конфигурации прошло успешно, но при выполнении отложенных обработчиков обновления в фоновом режиме происходит сбой. Попытка решить проблему «простым» путем — например, очисткой служебных констант — приводит к полной остановке автоматического обмена данными без видимых сообщений об ошибках.
В этой статье мы подробно разберем, почему возникает подобное поведение системы, как взаимосвязаны механизмы отложенного обновления Библиотеки стандартных подсистем (БСП) и регламентные задания обмена данными, а также рассмотрим пошаговые инструкции по восстановлению полной работоспособности базы данных.
Проанализируем детально причины возникновения этих ошибок и методы их устранения.
---
В современных конфигурациях 1С процесс обновления базы данных разделен на два этапа:
Для управления очередью отложенного обновления БСП использует служебную константу ДанныеДляОтложенногоОбновления и регистр сведений ОбработчикиОбновления. Если в системе остаются незавершенные обработчики или фоновые задания завершились аварийно, БСП применяет встроенную защиту:
БСП принудительно блокирует автоматический запуск регламентных заданий обмена данными (РИБ).
Это необходимо для того, чтобы недообновленные или некорректные данные из главного узла не мигрировали в подчиненные узлы РИБ, что могло бы вызвать глобальный рассинхрон и разрушение ссылочной целостности всей распределенной системы.
Когда администратор вручную сбрасывает или очищает константу ДанныеДляОтложенногоОбновления, он совершает грубую ошибку. Система «ослепляет» саму себя: очередь фоновых задач очищается, но маркеры успешного завершения обновления (такие как константа ОтложенноеОбновлениеЗавершеноУспешно) не принимают значение Истина, а в регистре ОбработчикиОбновления зависают ошибочные статусы. В итоге обмены РИБ по расписанию просто не стартуют, при этом ручной запуск обмена может проходить без явных ошибок на клиенте.
---
При анализе журнала регистрации или монитора регламентных заданий часто обнаруживается ошибка:
В данной транзакции уже происходили ошибки!
Выясним причину этой ошибки на уровне платформы 1С и СУБД:
Попытка — Исключение, платформа перехватывает первичную ошибку (конфликт блокировок) и управление передается в блок Исключение.В данной транзакции уже происходили ошибки!.Именно эта вторичная ошибка записывается в журнал регистрации, маскируя реальную причину сбоя (конфликт блокировок при заполнении Календаря оплат).
---
Рассмотрим подробнее шаги, которые позволят локализовать конфликт блокировок, восстановить структуру метаданных БСП и запустить регламентные обмены.
Для того чтобы увидеть первопричину ошибки, откроем Журнал регистрации в режиме «1С:Предприятие»:
Транзакция (нажмем правой кнопкой мыши по ошибочному событию и выберем «Отфильтровать по значению в колонке»).В данной транзакции уже происходили ошибки!. Там обязательно будет зафиксирован конфликт блокировок или ошибка СУБД с указанием конкретной таблицы (например, регистра накопления расчетов с клиентами или календаря оплат).По умолчанию БСП пытается выполнять отложенные обновления параллельно в несколько потоков (обычно до 8 потоков фоновых заданий). При обновлении тяжелых регистров (таких как Календарь оплат) потоки начинают блокировать друг друга на уровне СУБД.
Попробуем временно перевести обновление в однопоточный режим. Для этого запустим базу данных в режиме «1С:Предприятие» с параметром командной строки:
/C ЧислоПотоковОбновления=1
Также мы можем жестко задать это значение программно, выполнив в консоли кода следующий фрагмент:
// Установка однопоточного режима обновления для предотвращения взаимных блокировок
Константы.КоличествоПотоковОбновленияИнформационнойБазы.Установить(1);
Поскольку константа ДанныеДляОтложенногоОбновления была очищена вручную, нам необходимо заставить БСП перерегистрировать данные к обновлению. Выполним следующие действия по шагам:
/C ЗапуститьОбновлениеИнформационнойБазы
РезультатыОбновленияПрограммы напрямую).Если обновление Календаря оплат для вашей специфики работы в данный момент не является критически важным, а восстановить обмены в РИБ требуется незамедлительно, мы можем принудительно изменить статус зависших обработчиков на «Выполнен».
Для этого воспользуемся встроенным механизмом «Функции для технического специалиста» (в старых версиях — «Все функции»):
ОбработчикиОбновления.
// Программный сброс зависших обработчиков обновления БСП
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Обработчики.ИмяОбработчика КАК ИмяОбработчика
|ИЗ
| РегистрСведений.ОбработчикиОбновления КАК Обработчики
|ГДЕ
| Обработчики.Статус В (ЗНАЧЕНИЕ(Перечисление.СтатусыОбработчиковОбновления.Ошибка),
| ЗНАЧЕНИЕ(Перечисление.СтатусыОбработчиковОбновления.Выполняется))";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
МенеджерЗаписи = РегистрыСведений.ОбработчикиОбновления.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ИмяОбработчика = Выборка.ИмяОбработчика;
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
МенеджерЗаписи.Статус = Перечисления.СтатусыОбработчиковОбновления.Выполнен;
МенеджерЗаписи.Записать();
ВызватьИсключение "Принудительно завершен обработчик: " + Выборка.ИмяОбработчика; // Опционально для лога
КонецЕсли;
КонецЦикла;
// Разблокируем механизмы обмена БСП, установив финальную константу в Истина
Константы.ОтложенноеОбновлениеЗавершеноУспешно.Установить(Истина);
После выполнения данного кода механизмы БСП увидят, что все обработчики успешно завершены, снимут внутреннюю блокировку, и регламентные задания обмена РИБ автоматически возобновят свою работу по расписанию.
---
Если конфликт блокировок при обновлении базы продолжает воспроизводиться, нам потребуется настроить Технологический журнал (ТЖ) на сервере 1С:Предприятия. Это единственный способ узнать, какой именно пользовательский сеанс или фоновое задание конкурирует с процессом обновления календаря оплат.
Для этого создадим текстовый файл конфигурации logcfg.xml и поместим его в каталог настроек сервера 1С (обычно C:\Program Files\1cv8\conf\). Содержимое файла должно быть следующим:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\v8_logs" history="24">
<event>
<eq property="Name" value="TTIMEOUT"/>
</event>
<event>
<eq property="Name" value="TDEADLOCK"/>
</event>
<event>
<eq property="Name" value="EXCP"/>
</event>
<property name="all"/>
</log>
</config>
Проанализируем события в полученных логах технологического журнала:
TTIMEOUT покажет точное время ожидания на СУБД, превысившее лимит (по умолчанию 20 секунд). В логе будет указан заблокированный ресурс (таблица СУБД) и идентификаторы конфликтующих сессий.TDEADLOCK зафиксирует факт взаимной блокировки двух параллельных потоков и укажет транзакцию, которая была выбрана СУБД в качестве «жертвы» для отката.EXCP зафиксирует системные исключения платформы, предшествующие ошибке отката транзакции.На основе этих данных мы сможем принять решение о временном завершении активных сеансов конкретных пользователей или отключении конфликтующих фоновых заданий на время выполнения процедур обновления.
---
Подводя итоги, сформулируем основные правила при возникновении сбоев отложенного обновления в РИБ:
В данной транзакции уже происходили ошибки!./C ЧислоПотоковОбновления=1.