Предыстория проблемы обновления истории
Столкнулись с проблемой вылетания сеансов 1С в базах, работающих в клиент-серверном режиме работы с ошибкой “Удаленный сеанс принудительно разорвал соединение…”. Причем вылетали не все сразу сеансы у всех пользователей. А частями. Но если открыть 1С и просто ждать, то в течение часа-двух сеанс точно завершался с ошибкой. Про решение этой проблемы мы написали статью, привели в ней все разобранные возможные причины проблемы: Ошибка обращения к серверу 1С:Предприятия. Удаленный хост принудительно разорвал соединение.
При разборе проблемы оказалось, что периодически завершаются рабочие процессы по причине очень длительных запросов к серверу, которые никак не завершались. При аварийном завершении рабочего процесса 1С завершались с ошибкой все пользовательские сеансы. Но так как рабочих процессов 1С было несколько, “вылетали” не все базы 1С сразу. Часть продолжала работу. Завершались только те, в которых был этот проблемный сеанс.
Далее нашли проблемный сеанс. Это всегда было фоновое задание из нашей управленческой базы. Там было много конфликтов блокировок. Стали бороться с блокировками, более редко запускать регламентные задания, добиваться того, чтобы разные регламентные задания не запускали фоновые задания в одно время. Но и это не было причиной проблемы.
В конце оказалось, что есть только одно регламентное задание, запуск которого гарантированно вызывает ошибку. И в нем в итоге нашли строку кода, которая приводит к аварийному завершению рабочего процесса сервера 1С.
Это была строка кода для обновления истории данных:
ИсторияДанных.ОбновитьИсторию(Истина, Истина);
Как работает ИсторияДанных в платформе 1С
В момент записи объекта, если для него включено платформенное версионирование, информация об изменениях попадает в таблицу _DataHistoryQueue0. В момент запуска процедуры ИсторияДанных.ОбновитьИсторию() запись в таблице _DataHistoryQueue0 удаляется и появлется запись в таблице версий _DataHistoryVersions.
Если у объекта метаданных в конфигураторе включен флаг Обновлять историю сразу после записи, это происходит сразу в момент записи.
В интернете нашли две подробные статьи с описанием похожей проблемы - на Инфостарте и на Хабре.
Эти статьи нам очень помогли в решении задачи. Но в обеих статьях причина проблемы была не такая, как в нашем случае. В нашей базе записей в таблице _DataHistoryQueue0 было немного (85 штук в момент проверки), зависать фоновое задание из-за этого не могло. Общие реквизиты в конфигурации не использовались. При этом запуск полного обновления истории данных всегда прерывался с ошибкой. Версия платформы 1С была 8.3.25.1374. Далее опишем, как искали причину проблемы.
Локализация проблемы обновления истории данных
-
Раз полное обновление истории данных приводило к аварийному завершению рабочего процесса 1С (не только сеанса в 1С, а сразу рабочего процесса), стали искать объект метаданных, при выполнении обновления истории которого происходит ошибка. Написали следующий код:
Для Каждого ВидМетаданных Из Метаданные.Документы Цикл
Массив = Новый Массив();
Массив.Добавить(ВидМетаданных);
ЗаписьЖурналаРегистрации("ОбновитьИсториюПоОбъектамМетаданных.ВидМетаданных", УровеньЖурналаРегистрации.Информация, , , ВидМетаданных.Имя);
ИсторияДанных.ОбновитьИсторию(Массив, , Истина, Истина);
КонецЦикла; - Алгоритм ожидаемо завершается с ошибкой. Проверяем в журнале регистрации, запись по событию ОбновитьИсториюПоОбъектамМетаданных.ВидМетаданных с каким комментарием записана. Именно это и есть вид документа, по которому происходит проблема.
В нашем случае это был документ с именем Задача.
Попытка исправления ошибки через очистку таблицы _DataHistoryQueue0
В статье на Инфостарте говорилось про некоррректный тип значения у отдельных записей таблицы _DataHistoryQueue0. Для ухода от этой проблемы сделали очистку этой таблицы. После накопления новых изменений задач ошибка вернулась. Полное обновление истории данных стало снова приводить к аварийному завершению рабочего процесса сервера 1С.
Исправление через отключение истории для документа и повторное включение
Порядок действий:
- Очистили таблицу _DataHistoryQueue0 в pg_admin с помощью скрипта: DELETE FROM public._datahistoryqueue0 WHERE true
- Отключили в конфигураторе использование истории данных для проблемного объекта метаданных (документ Задача в нашем случае)
- Выполнили реструктуризацию таблицу БД
- Включили использование истории в режиме 1С:Предприятие.
После проделанных действий команда ИсторияДанных.ОбновитьИсторию() в большинстве случаев стала выполняться без ошибок. Но все равно периодически рабочий процесс 1С завершался при запуске этой команды с ошибкой.
Избавиться от ошибки полностью получилось только после удаления из самописаной конфигурации 1С общих реквизитов. Это тоже не так просто получилось сделать. О возникшей ошибке и как ее решали написали отдельную статью: Таблица или поле Fld1898 не содержится в разделе FROM