Отложенное обновление 1С идёт который день: четыре проверки, после которых ясно, ждать или чинить
Иван Недомолков · Chop etilgan:
После перехода типовой на новую редакцию отложенные обработчики идут фоном, и вопрос от бухгалтерии приходит всегда один: “когда это кончится?”. Если база большая, ответить нечем. На форуме Инфостарта лежит характерный случай: 450 ГБ, переход УТ с 11.4 на 11.5, четырнадцатый день работы обработчиков, пройдено около 70 %. Работать тяжело, а понять, нормально это или нет, никто не может.
Короткий ответ у этой задачи есть. Очередь отложенного обновления в БСП 3.1 целиком лежит в нескольких регистрах, и по ним за пару запросов видно две вещи: ориентировочное время окончания и обработчик, который держит всех остальных. Ниже порядок проверки, который мы используем у себя, с запросами и с теми местами, где штатные инструменты подсказывают неверно.
Все замеры в тексте сняты на копии УТ 11.5.22 с БСП 3.1.11: отложенное обновление там
перезапускали штатным ПерезапуститьОтложенноеОбновление, в очереди было 215 обработчиков
(207 параллельных, 8 последовательных), прошла она за четыре часа.
Почему штатных форм не хватает
| Что смотрим | Что оно говорит | Чего не говорит |
|---|---|---|
| Форма “Результаты обновления программы" | "Выполнено: N из M”, индикатор | когда закончится, что мешает |
| Отчёт “Прогресс отложенного обновления” | процент, остаток в объектах | время окончания; про застрявший обработчик только “возможно, другие обработчики держат его выполнение” |
| Список отложенных обработчиков | статус и последняя ошибка | что ошибка “зацикливание” бывает следствием блокировки |
При этом данные для ответа числом БСП уже собирает сама: сколько объектов обработано в каждом часу, когда завершился каждый обработчик, сколько у него было попыток, текст последней ошибки, остаток в плане обмена. Остаётся их сложить.
Проверка 1. Работает ли регламентное задание вообще
Начинать стоит с причины, которая останавливает всю очередь разом. В клиент-серверной базе отложенное обновление выполняет регламентное задание “Отложенное обновление”, по типовому расписанию раз в минуту. Задание выключено или у базы стоит флаг “Блокировка регламентных заданий” в консоли администрирования серверов 1С - и очередь не двигается совсем, разбирать обработчики в этом случае бессмысленно.
Задания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(
Новый Структура("Метаданные", Метаданные.РегламентныеЗадания.ОтложенноеОбновлениеИБ));
Если Задания.Количество() > 0 Тогда
Фоновые = ФоновыеЗадания.ПолучитьФоновыеЗадания(
Новый Структура("РегламентноеЗадание", Задания[0]));
КонецЕсли;
// Задание включено, а фонового запуска давно не было: смотреть флаг в консоли серверов 1С
На копии мы попались ровно на это: база была создана с запретом регламентных заданий, в конфигурации задание включено, фоновых заданий ноль. Этот случай, к слову, ловит и штатная форма, она пишет “Вероятно включена блокировка выполнения регламентных заданий”. Остальные три проверки штатные формы не делают.
Проверка 2. Нет ли обработчика, у которого кончились попытки
Упавший обработчик БСП не бросает: ставит статус “Ошибка”, прибавляет счётчик попыток
и запускает позже ещё раз. Потолок попыток в БСП 3.1.11 задаёт функция
МаксимумПопытокОбновления:
| Обработчик | Предел попыток |
|---|---|
| обычный | 3 |
| многопоточный (параллельный, данные которого БСП делит на порции между потоками) | 3 * (объекты * регистры + потоки), где объекты и регистры это число таблиц из параметров его выборки |
Обработчик, упёршийся в предел, больше не стартует. Отложенное обновление при этом
заканчивается сообщением “Не все процедуры удалось выполнить”, а последний обработчик
очереди, ОчиститьУстаревшиеДанныеПолностью, так и не запускается, потому что ждёт всех.
Это главный подозреваемый, и найти его можно одним запросом к регистру
ОбработчикиОбновления:
Запрос = Новый Запрос(
"ВЫБРАТЬ
| О.ИмяОбработчика КАК Имя,
| О.Статус КАК Статус,
| О.ЧислоПопыток КАК Попыток,
| О.ИнформацияОбОшибке КАК Ошибка,
| О.ОчередьОтложеннойОбработки КАК Очередь,
| О.СтатистикаВыполнения КАК Статистика,
| О.ОбрабатываемыеДанные КАК Данные
|ИЗ
| РегистрСведений.ОбработчикиОбновления КАК О
|ГДЕ
| О.РежимВыполнения = ЗНАЧЕНИЕ(Перечисление.РежимыВыполненияОбработчиков.Отложенно)");
Статусов пять: не выполнялся, выполняется, выполнен, ошибка, приостановлен. Отбираете
“Ошибка” и сравниваете ЧислоПопыток с пределом.
Не удивляйтесь, если попыток окажется больше предела, а запусков вы насчитали меньше.
Счётчик растёт не только от исключения. Если обработчик минимальной очереди отработал
и не обработал ни одного объекта, БСП добавляет ему попытку как подозрение на зацикливание
(процедура ПослеЗапускаПроцедурыОбработкиДанных в ОбновлениеИнформационнойБазыСлужебный).
У нас два запуска одного обработчика дали счётчик 4 при пределе 3.
Что делать с таким обработчиком. Прочитать полный текст ошибки, устранить причину и запустить его кнопкой “Запустить” в форме “Отложенные обработчики”. Счётчик попыток правкой регистра не сбрасывайте.
Если пишете свою внешнюю обработку
Регистра ОбработчикиОбновления нет в старых БСП: в 3.1.2 (Бухгалтерия для Казахстана
3.0.40) и в 2.4.6 (УТ для Казахстана 3.4) очередь хранится деревом в константе
СведенияОбОбновленииИБ, колонки статуса и попыток там те же. На 3.1.11 регистр есть.
Поэтому прямые вызовы ОбновлениеИнформационнойБазыСлужебный из кода обработки не годятся:
на конфигурации без такого модуля обработка не откроется вовсе. Всё, что зависит от версии,
держите в тексте запроса, а наличие регистра проверяйте через Метаданные заранее.
Проверка 3. Почему обработчик упал: журнал регистрации
Текст ошибки в регистре часто врёт о причине. Обработчики пишут в журнал под событием “Обновление информационной базы”, и здесь три ловушки сразу.
Уровень записи зависит от попытки. Пока попытки остаются, ошибка обработчика ложится в журнал как “Предупреждение”. “Ошибкой” она становится только на последней попытке. На копии первый запуск сломанного обработчика оставил 39 предупреждений и ни одной ошибки. Отбор журнала “Уровень = Ошибка” этот запуск не покажет вообще, ставьте отбор по “Предупреждению”.
Имени обработчика в тексте может не быть. У нас первая строка ошибки звучала так: “Не удалось обработать некоторые виды контактной информации (пропущены): 38”. Какой это обработчик, видно лишь из стека ниже. Связать запись с обработчиком помогает то, что БСП перед каждым запуском пишет в том же сеансе строку “Выполняется процедура обновления” с именем:
Маркер = "Выполняется процедура обновления """;
Для Каждого Запись Из ТаблицаЖурнала Цикл
Если СтрНачинаетсяС(Запись.Комментарий, Маркер) Тогда
Хвост = Сред(Запись.Комментарий, СтрДлина(Маркер) + 1);
ОбработчикСеанса.Вставить(Запись.Сеанс, Лев(Хвост, СтрНайти(Хвост, """") - 1));
Продолжить;
КонецЕсли;
// следующие предупреждения и ошибки сеанса относим к ОбработчикСеанса[Запись.Сеанс]
КонецЦикла;
Одинаковые ошибки выглядят разными. Каждый пропущенный элемент даёт свою запись с именем элемента в кавычках:
Не удалось обработать "Мобильный телефон" по причине:
Ошибка при вызове метода контекста (Заблокировать)
{Справочник.ВидыКонтактнойИнформации.МодульМенеджера(642)}:Блокировка.Заблокировать();
...
Конфликт блокировок при выполнении транзакции:
Превышено максимальное время ожидания предоставления блокировки
Сравните тексты целиком - получите 38 разных ошибок. Выкиньте то, что в кавычках, и возьмите последнюю строку - получите одну ошибку, повторённую 38 раз. Для вопроса “что держит” нужен второй способ.
Как блокировка превращается в “зацикливание”
Чтобы увидеть это своими глазами, мы уронили обработчик нарочно: из соседнего сеанса взяли исключительную управляемую блокировку на весь справочник видов контактной информации и держали открытую транзакцию. Обработчику предстояло пройти 38 элементов.
Что происходило дальше:
- Каждый элемент ждал блокировку положенные 20 секунд и пропускался. Один запуск занял 13 минут, всё это время статус был “Выполняется”, штатная форма не менялась.
- Запуск кончился статусом “Ошибка”, попытка 2 из 3. В регистре текст про 38 пропущенных элементов, слова “блокировка” в нём нет.
- Второй раз БСП взялась за обработчик в 15:57, когда большая часть очереди уже прошла. Снова 12 минут 41 секунда ожидания, снова 38 пропусков.
- Счётчик стал 4 при пределе 3, а последней ошибкой в регистре встало “Произошло зацикливание процедуры обработки данных. Выполнение прервано.”
Отчёт БСП и список обработчиков показывают именно “зацикливание”, и человек идёт искать бесконечный цикл в коде обработчика. Настоящая причина лежит в журнале: 76 предупреждений по элементам, по 38 за запуск, с одной и той же последней строкой про ожидание блокировки.
Держателя блокировки ищут по списку сеансов, и самый долгий сеанс тут кандидат, а не доказательство. У нас держало COM-соединение, а в списке оно стояло третьим: выше висели два сеанса от прерванных процессов. На рабочих базах чаще держит забытая обработка или обмен. Если блокировки на сервере возникают регулярно, их удобнее разбирать не руками: для этого есть анализ нагрузки кластера, который показывает, кто кого ждал.
Проверка 4. Когда закончится
Если первые три проверки чистые, остаётся посчитать срок. Здесь две меры скорости, и одной из них мало.
Остаток в объектах. БСП регистрирует данные для отложенных обработчиков в плане обмена
ОбновлениеИнформационнойБазы, узел соответствует номеру очереди (обработчики очереди 2
ждут, пока очередь 1 пройдёт общие с ними данные). Обработчик прошёл объект, запись
изменений удаляется. Остаток это число записей в таблицах изменений по составу плана:
ТекстЗапроса =
"ВЫБРАТЬ
| Т.Узел.Очередь КАК Очередь,
| КОЛИЧЕСТВО(*) КАК Количество
|ИЗ
| Справочник.ВидыКонтактнойИнформации.Изменения КАК Т
|ГДЕ
| Т.Узел.Временная = ЛОЖЬ
|СГРУППИРОВАТЬ ПО
| Т.Узел.Очередь";
// по всему составу плана такие запросы склеиваются через ОБЪЕДИНИТЬ ВСЕ
Отбор по Временная нужен из-за перезапусков: БСП регистрирует данные на новые временные
узлы, а закончив, меняет пометки местами, и старые узлы становятся временными с пустой
регистрацией. Ещё одна деталь: часть записей плана не принадлежит ни одному текущему
обработчику. На копии по всему составу было 277 записей, а за обработчиками числилось 195;
разница пришлась на хвосты шести справочников интеграций. Штатный отчёт такие строки тоже
не считает, связь “объект - обработчик” берётся из ОбрабатываемыеДанные.
Скорость в объектах. Регистр ПрогрессОбновления хранит обработанные объекты по часам,
так что скорость видна с первого замера:
Запрос = Новый Запрос(
"ВЫБРАТЬ
| П.ИмяОбработчика КАК Имя,
| СУММА(ВЫБОР КОГДА П.ИнтервалЧас >= &НачалоОкна
| ТОГДА П.ОбъектовОбработано ИНАЧЕ 0 КОНЕЦ) КАК ЗаОкно
|ИЗ
| РегистрСведений.ПрогрессОбновления КАК П
|СГРУППИРОВАТЬ ПО
| П.ИмяОбработчика");
Запрос.УстановитьПараметр("НачалоОкна", НачалоЧаса(ТекущаяДатаСеанса()) - 3600);
Окно идёт от начала прошлого часа до текущего момента, делить надо на фактически прошедшие
секунды. Историю за прошлые сутки здесь искать бесполезно: БСП сама чистит интервалы
раньше начала текущего дня (процедура ОчиститьПрогрессОбработкиЗаИнтервалыПредыдущегоДня),
поэтому в половине первого ночи у вас будет полчаса истории.
Скорость в обработчиках. Время завершения каждого обработчика лежит
в СтатистикаВыполнения:
Статистика = Выборка.Статистика.Получить(); // Соответствие
Если ТипЗнч(Статистика) = Тип("Соответствие")
И ТипЗнч(Статистика["ЗавершениеОбработкиДанных"]) = Тип("Дата")
И Статистика["ЗавершениеОбработкиДанных"] >= НачалоОкна Тогда
ВыполненоЗаОкно = ВыполненоЗаОкно + 1;
КонецЕсли;
Прогноз считается обоими способами, и берётся более поздняя дата.
Три ошибки в расчёте, на которые мы наступили
| Ошибка | Что видно | Как правильно |
|---|---|---|
| Считать только по объектам | через три минуты после старта остаток стоит на 195, расчёт кричит “стоит” | первыми идут последовательные обработчики, объектов в плане обмена у них нет: они завершались по одному в минуту, при этом “Выполнено: N из 215” росло. Нужна вторая мера, обработчики в час |
| Брать обработанное из прогресса как есть | обработчик групп значений доступа ничего не регистрировал, а в прогресс записал 867; расчёт дал 3 150 объектов в час и конец “через четыре минуты” | обрезать обработанное зарегистрированным, как это делает штатный отчёт: 867 превращаются в 0, итог за 58 минут 12 объектов в час, и остаток за тот же час упал со 195 до 183, ровно на 12 |
| Делить весь остаток на общую скорость | 183 объекта по 12 в час дают окончание в пять утра | 116 из 183 принадлежали обработчику, который ещё ждал очереди и прошёл бы их за один запуск. Считать по объектам надо только обработчики в работе, каждый по своей скорости, и брать самую позднюю дату; ждущих покрывает прогноз по обработчикам |
Как прогноз вёл себя на живой очереди
Очередь стартовала в 13:01. Первый прогноз появился в 13:10 и до 13:21 держался около 17:00-17:30. С 13:20 до 13:33 не завершилось ни одного обработчика, регламентное задание все тринадцать минут было занято тем самым обработчиком на блокировке, и прогноз уехал с 17:20 на 19:50. Когда затор прошёл, к 14:00 он вернулся к 17:50-18:00.
Очередь закончилась в 17:05. Прогноз в 13:10 ошибся на 25 минут, в 14:01 на 45, а с 15:06
стоял на “около 17:00” почти час без изменений. Средний темп вышел около 52 обработчиков
в час. Закончилась очередь, впрочем, неуспехом: два обработчика остались невыполненными,
среди них наш заблокированный, а ОчиститьУстаревшиеДанныеПолностью так и не запустился.
Обратите внимание на 13-минутный затор. Задание активно, обработчик “Выполняется”, вокруг ничего не меняется. Объявить это остановкой через пять минут было бы неправдой: тревогу здесь подаёт сам прогноз, уезжая вперёд. Красный сигнал разумно давать в двух случаях: есть обработчик с исчерпанными попытками, или за последний час не обработано ни одного объекта и не завершилось ни одного обработчика.
Что это значит для базы с форума
Расчёт “70 % за 14 дней, значит, ещё шесть” на большой базе не работает. Оставшиеся проценты легко могут принадлежать одному тяжёлому обработчику, который идёт по миллионам документов, и тогда срок определяет только его собственная скорость. По логике расчёта выше так и будет: его остаток делится на его скорость.
Честная граница: на нашей копии объектов в очереди было меньше двухсот, прогноз там шёл в основном по обработчикам, и на очереди с миллионами объектов мы этот расчёт вживую не видели. Время самого замера на таком плане обмена тоже не мерили; на копии он занимал 0,14-0,18 секунды.
Готовая обработка
Всё описанное собрано во внешнюю обработку “Отложенное обновление: когда закончится и что держит”, она продаётся на Инфостарте за 10 SM, код открыт. При открытии делает замер и выводит одну цветную строку: идёт и закончится около такого-то часа, или стоит, и вот обработчик. Кнопка “Кто держит” раскрывает виновника с полным текстом ошибки и числом одинаковых записей журнала, отчёт для администратора и выгрузка в Markdown для нейросети собираются без паролей и без имён пользователей. Обработка только читает, перезапуск остаётся в штатной форме. Примеры её строк на живой очереди и требования к БСП - на странице инструмента.
Если после обновления перестали открываться дополнительные обработки и отчёты, это отдельная история, разобранная в статье внешняя обработка после обновления 1С. А если не запускается вообще никакое регламентное задание, начните с разбора, почему регламентное задание 1С не выполняется.
Переход типовой на новую редакцию, в том числе казахстанских конфигураций, мы берём и целиком: план обновления, репетиция на копии, разбор отложенных обработчиков после него. Подробности на странице сопровождения типовых конфигураций.