Как устранить ошибку таймаута и конфликта блокировок при синхронизации РИБ на PostgreSQL?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

При выполнении обмена данными в распределенной информационной базе (РИБ) или при попытке прочитать зарегистрированные изменения через специализированные обработки (например, РегистрацияИзмененийДляОбмена8_2) пользователи могут столкнуться с критической ошибкой:

«Конфликт блокировок при выполнении транзакции: Превышено максимальное время ожидания предоставления блокировки».

Ошибка часто проявляется в момент вызова метода ПрочитатьИзменения() или при выполнении прямых запросов к виртуальным таблицам изменений объектов конфигурации. Разберем причины возникновения этой ситуации и пошаговые варианты ее устранения.

Анализ механизма возникновения ошибки

Проанализируем типовой участок кода, на котором происходит сбой при чтении данных узла обмена. При подсчете или выборке измененных объектов выполняется обращение к таблицам регистрации изменений:


Функция ПолучитьКоличествоЗарегистрированныхОбъектовДляМетаданногоПоУзлу(МетаданныеОбъекта)
    
    Запрос = Новый Запрос();
    ИмяТаблицы = ПолучитьПоМетаданномуНазвание(МетаданныеОбъекта);
    
    Если ПустаяСтрока(ИмяТаблицы) Тогда
        Возврат 0;
    КонецЕсли;
    
    ИмяТаблицы = ИмяТаблицы + "." + МетаданныеОбъекта.Имя + ".Изменения";
    
    Запрос.Текст = "ВЫБРАТЬ
                   |    Количество(*) КАК Количество
                   |ИЗ
                   |    " + ИмяТаблицы + " КАК РегистрацияИзменений
                   |ГДЕ
                   |    РегистрацияИзменений.Узел = &Узел";
                   
    Запрос.УстановитьПараметр("Узел", УзелОбмена);
    
    ТаблицаДанных = Запрос.Выполнить().Выгрузить();
    
    Если ТаблицаДанных.Количество() = 0 Тогда
        Возврат 0;
    Иначе        
        Возврат ТаблицаДанных[0].Количество;        
    КонецЕсли;
    
КонецФункции

В момент выполнения метода Запрос.Выполнить() происходит обращение к служебным таблицам СУБД (например, _ReferenceChngr, _DocumentChngr). Выясним основные причины возникновения таймаута:

  1. Ошибки платформы 1С:Предприятие (в частности, ветки 8.3.9). В некоторых релизах платформы при обработке таблиц регистрации изменений накладываются избыточные управляемые блокировки даже на операции чтения. При наличии режима совместимости с устаревшими версиями платформа может некорректно транслировать запросы в СУБД.
  2. Нехватка ресурсов пула блокировок PostgreSQL. При последовательном обходе большого количества метаданных конфигурации транзакция удерживает множество дескрипторов блокировок, что приводит к исчерпанию лимитов СУБД.
  3. Накопление большого объема невыгруженных изменений. При большом объеме записей в таблицах регистрации планировщик PostgreSQL переходит на последовательное сканирование (Seq Scan), увеличивая время выполнения запроса свыше установленного таймаута блокировки.

Способ 1. Понижение или повышение версии платформы 1С

Если проблема проявилась сразу после перехода на проблемную версию платформы 1С (например, 8.3.9.2033 или 8.3.9.1850), наиболее надежным и быстрым решением является корректировка версии платформы:

  1. Откат на стабильную ветку. Возврат на проверенные релизы (например, 8.3.8.1652) полностью устраняет конфликт блокировок при чтении таблиц планов обмена.
  2. Обновление на актуальный релиз. Если возврат на старую версию невозможен, выполним обновление платформы до актуальных версий ветки 8.3.10 и выше, где зарегистрированные ошибки трансляции блокировок при работе с РИБ были исправлены.

Способ 2. Корректировка режима совместимости конфигурации

Проанализируем параметры конфигурации в дереве метаданных. В ряде случаев платформа 1С при установленном режиме совместимости Версия 8.2.13 или Версия 8.2.16 накладывает блокировки по устаревшим правилам.

  1. Откроем Конфигуратор и перейдем в свойства корневого элемента конфигурации.
  2. Найдем свойство Режим совместимости.
  3. Если используется устаревший режим, изменим его на Версия 8.3.5 или выше (при условии, что код конфигурации адаптирован под данный режим).
  4. Сохраним конфигурацию базы данных и перезапустим рабочие процессы сервера 1С.

Способ 3. Оптимизация параметров PostgreSQL

Настроим параметры СУБД в конфигурационном файле postgresql.conf для предотвращения дефицита разделяемой памяти под блокировки:

  1. Найдем параметр max_locks_per_transaction. По умолчанию он равен 64. Для баз 1С с разветвленной структурой метаданных и активным использованием РИБ увеличим значение до 256 или 512:

    max_locks_per_transaction = 256

  2. Проверим параметр deadlock_timeout. Рекомендуемое значение для работы с 1С составляет 1s (1000 мс):

    deadlock_timeout = 1s

  3. Сохраним файл postgresql.conf и выполним перезапуск службы СУБД.

Способ 4. Очистка и перерегистрация изменений

Если таблицы регистрации изменений содержат некорректные записи или поврежденные ссылки, очистим регистрацию для проблемного узла и зарегистрируем объекты заново программным способом:


// Полное удаление регистрации изменений по проблемному узлу
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена);

// Выборочная регистрация только необходимых типов объектов
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Метаданные.Справочники.Номенклатура);
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Метаданные.Документы.РеализацияТоваровУслуг);

Способ 5. Оптимизация программного кода чтения изменений

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


ТаблицаДанных = Запрос.Выполнить().Выбрать();

Если ТаблицаДанных.Следующий() Тогда
    Возврат ТаблицаДанных.Количество;
Иначе        
    Возврат 0;        
КонецЕсли;

Для гарантированного выявления конкретного источника блокировок в сложных случаях настроим Технологический журнал с отслеживанием событий TLOCK и TTIMEOUT, что позволит определить точный контекст кода и имена таблиц, на которых сеансы ожидают освобождения ресурсов.

← На главную