Переход с MS SQL Server на PostgreSQL в среде 1С:Предприятие часто сопровождается возникновением специфических ошибок, которые не проявлялись ранее. Одной из наиболее критичных проблем являются ошибки вида terminating connection due to transaction timeout или cancelling statement due to statement timeout. Эти ошибки возникают внезапно, блокируя запись документов, справочников или проведение транзакций. Проанализируем причины такого поведения и разберем пошаговый алгоритм диагностики и решения проблемы.
Ситуация, когда база данных годами стабильно работала на Windows и MS SQL, а после миграции на Astra Linux и PostgreSQL начала «сыпаться» с таймаутами, — классический сценарий. Рассмотрим основные технические факторы, вызывающие такую разницу в поведении:
transaction_timeout, который ограничивает общую длительность транзакции. Даже если один запрос выполняется быстро, суммарное время транзакции может превысить лимит.Прежде всего, нам необходимо убедиться, что проблема не вызвана слишком жесткими ограничениями в postgresql.conf. Проанализируем текущие значения параметров. Для этого выполним запрос в консоли СУБД:
SELECT name, setting, unit, context
FROM pg_settings
WHERE name LIKE '%timeout%';
Особое внимание уделим следующим параметрам:
statement_timeout: время выполнения одного запроса. Для 1С рекомендуется устанавливать значение 0 (без ограничений).lock_timeout: время ожидания получения блокировки. Также рекомендуется 0.idle_in_transaction_session_timeout: время ожидания в транзакции без активности.transaction_timeout (актуально для PG 17): общее время жизни транзакции.Если мы видим значения, отличные от 0, их необходимо сбросить. Однако, как показывает практика, настройки могут быть заданы не только глобально, но и на уровне конкретной базы данных или пользователя.
Иногда параметры в postgresql.conf выглядят корректно, но ошибка сохраняется. Это происходит потому, что настройки могут быть переопределены для конкретного подключения. Проверим таблицу pg_db_role_setting, выполнив следующий запрос:
SELECT rolname AS "Role",
datname AS "Database",
pg_catalog.array_to_string(setconfig, E'\n') AS "Settings"
FROM pg_catalog.pg_db_role_setting
LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase
LEFT JOIN pg_catalog.pg_roles r ON r.oid = setrole
ORDER BY 1, 2;
Если этот запрос возвращает строки с параметрами таймаута, значит, ограничения заданы индивидуально. Для их сброса используйте команды ALTER ROLE ... RESET ... или ALTER DATABASE ... RESET ....
Рассмотрим дополнительные технические нюансы, которые могут вызывать задержки при записи, воспринимаемые платформой 1С как таймаут:
Отключение JIT-компиляции: В современных версиях PostgreSQL (16, 17) включена JIT-компиляция. Для специфических запросов 1С время компиляции плана запроса может превышать время его выполнения. Проанализируем ситуацию и попробуем отключить этот механизм:
# В файле postgresql.conf
jit = off
Настройка Huge Pages и THP: В Astra Linux по умолчанию может быть включен механизм Transparent Huge Pages (THP). Для баз данных это критично, так как вызывает микро-фризы при выделении памяти. Рекомендуется отключить THP на уровне ядра ОС и настроить использование обычных Huge Pages через параметр vm.nr_hugepages.
Оптимизация контрольных точек (Checkpoints): Ошибки при записи часто возникают в моменты сброса данных на диск. Увеличим параметры, чтобы сделать процесс записи более плавным:
max_wal_size = 4GB # Или более, в зависимости от объема данных
checkpoint_timeout = 15min
checkpoint_completion_target = 0.9
Если технические настройки СУБД верны (все таймауты в 0), а ошибка terminating connection due to transaction timeout все равно возникает, причина кроется в самом коде конфигурации. Рассмотрим, что именно нужно искать:
Взаимоблокировки в неоптимальных запросах: PostgreSQL крайне чувствителен к порядку обращения к таблицам. Если один запрос обновляет данные в порядке А-Б, а другой Б-А, возникнет взаимоблокировка. В MS SQL такие ситуации могли «проглатываться» или разрешаться иначе, но в Postgres они вызывают остановку процесса.
Длинные транзакции: Разберем типичную ошибку программиста 1С:
// Плохой пример: длительная обработка внутри транзакции
НачатьТранзакцию();
Пока Выборка.Следующий() Цикл
// Сложные расчеты, обращения к внешним API или файлам
Объект = Выборка.Ссылка.ПолучитьОбъект();
Объект.Записать();
КонецЦикла;
ЗафиксироватьТранзакцию();
В такой структуре транзакция остается открытой слишком долго. При переезде на PostgreSQL такие участки кода необходимо переписывать, вынося расчеты за пределы транзакции или выполняя запись порциями.
Проанализируем используемый дистрибутив СУБД. Для работы с 1С настоятельно рекомендуется использовать специализированные сборки (например, от Postgres Pro или официальные сборки с сайта 1С). Они содержат патчи, оптимизирующие работу с блокировками и планами запросов, специфичными для метаданных 1С.
Если вы используете версию 17, и ошибки продолжаются, рассмотрите временный откат на версию 16, так как 17-я версия на текущий момент является максимально новой и может содержать неучтенные в платформе 1С особенности поведения transaction_timeout.
Для успешного решения проблемы таймаутов выполните следующие действия:
statement_timeout, lock_timeout и transaction_timeout в значение 0 во всех файлах конфигурации и настройках ролей.pg_stat_activity) и настройте перенос логов в ClickHouse.JIT и настройте Huge Pages на уровне операционной системы.Помните, что PostgreSQL — это мощный инструмент, который требует более чистого и дисциплинированного кода запросов, чем MS SQL. Тщательный аудит конфигурации перед миграцией позволит избежать подобных проблем в промышленной эксплуатации.