В процессе эксплуатации связки платформы 1С:Предприятие 8.3 и СУБД PostgreSQL администраторы и разработчики иногда сталкиваются с внезапными аварийными завершениями работы пользователей. Одним из наиболее неприятных и труднодиагностируемых сбоев является критическая ошибка СУБД: ERROR: could not find replacement targetlist entry for attno XX. После появления этого сообщения сеанс работы в 1С аварийно завершается, а в логах фиксируется невосстановимая ошибка при выполнении POST-запроса к ресурсу /e1cib/logForm.
В этой статье мы подробно разберем причины возникновения данной ошибки на техническом уровне, выявим конкретные условия ее воспроизведения в прикладных конфигурациях 1С (таких как 1С:Зарплата и управление персоналом и 1С:Зарплата и кадры государственного учреждения), а также рассмотрим проверенные практические способы ее полного устранения.
Для того чтобы понять природу этой ошибки, нам необходимо заглянуть во внутренние механизмы работы планировщика запросов (Query Planner) и оптимизатора PostgreSQL. Ошибка could not find replacement targetlist entry for attno XX (где вместо XX выводится конкретный порядковый номер колонки, например, 15 или 22) является внутренним багом ядра PostgreSQL, связанным с механизмом перезаписи запросов (Query Rewriter) и оптимизацией планов выполнения.
Рассмотрим детально, как это происходит:
RETURNING (например, INSERT INTO ... RETURNING ... или UPDATE ... RETURNING ...).targetlist. Каждая колонка внутри движка СУБД идентифицируется по своему номеру — attno (attribute number).attno и логическим списком targetlist.Ниже представлен пример схематичной структуры запроса на уровне СУБД, при планировании которого оптимизатор старых версий PostgreSQL мог выдать ошибку сопоставления атрибутов:
-- Схематичный пример запроса, вызывающего сбой оптимизатора
SELECT
temp_table_1.id,
temp_table_1.period,
subquery.calculated_value
FROM temp_table_1
LEFT JOIN (
SELECT
parent_id,
col_1,
col_2,
col_15 AS calculated_value -- Ошибка планировщика при попытке найти attno 15
FROM temp_table_2
WHERE col_active = true
GROUP BY parent_id, col_1, col_2, col_15
) subquery ON temp_table_1.id = subquery.parent_id;
Анализ практических кейсов показывает, что наиболее часто данная ошибка проявляется в конфигурациях 1С:Зарплата и управление персоналом (ЗУП 3.1) и 1С:Зарплата и кадры государственного учреждения (ЗГУ 3.1) при попытке ввести исправление или провести документ Больничный лист.
Проанализировав поведение системы, специалисты выявили ключевую закономерность воспроизведения сбоя:
Данная проблема была зафиксирована на СУБД PostgreSQL версий 11.5-1.1C и некоторых сборках ветки PostgreSQL 10.8-13.1C под управлением платформ 1С:Предприятие версий 8.3.14.x и 8.3.15.x.
Если вы столкнулись с ошибкой could not find replacement targetlist entry for attno, у вас есть несколько путей ее решения — от быстрых временных мер до кардинального устранения первопричины.
Поскольку ошибка кроется непосредственно в коде планировщика запросов СУБД, разработчики из Postgres Professional совместно с фирмой 1С оперативно выпустили исправления. Проблема была полностью устранена в специализированных сборках СУБД.
Для устранения ошибки выполним обновление СУБД до следующих релизов (или более новых):
Как подтверждает практика администрирования, после перехода на указанные релизы ошибка при расчете больничных листов полностью исчезает, так как патч корректирует логику сопоставления целевых списков атрибутов в оптимизаторе.
Многие системные администраторы отмечают, что стандартные сборки, поставляемые непосредственно фирмой 1С, иногда могут содержать досадные ошибки компиляции или сборки пакетов. В качестве надежной альтернативы рассмотрим переход на дистрибутивы от компании Postgres Professional, которые оптимизированы специально под требования платформы 1С:Предприятие.
Если у вас нет возможности оперативно согласовать и провести обновление СУБД на продакшн-сервере до последних патчей, но расчетный отдел требует срочно провести больничные листы, рассмотрим варианты временного даунгрейда (отката) версии PostgreSQL:
9.6.7 и выше указанный баг планировщика гарантированно отсутствует.Проанализируем важный аспект, который часто упускают системные администраторы. Просто установить исправленную версию PostgreSQL "из коробки" недостаточно для ее стабильной и быстрой работы под нагрузкой 1С. Любая сборка СУБД требует обязательной базовой настройки конфигурационного файла postgresql.conf.
Разберем основные параметры, которые необходимо скорректировать сразу после установки чистой СУБД, чтобы избежать просадок производительности:
shared_buffers — установите объем разделяемой памяти СУБД. Для выделенного сервера рекомендуется задавать значение в размере 25% от общего объема оперативной памяти (RAM) сервера.effective_cache_size — задайте значение в размере 50-75% от общего объема RAM. Это подскажет планировщику СУБД, какой объем памяти доступен для кэширования данных операционной системой.work_mem — лимит памяти для выполнения операций сортировки и группировки внутри одного запроса. Для баз 1С рекомендуется устанавливать значения в пределах 32MB – 128MB (в зависимости от сложности запросов и количества активных пользователей). Превышение этого параметра при большом количестве соединений может исчерпать всю физическую память сервера.temp_buffers — объем памяти под временные таблицы одного сеанса. Рекомендуется установить значение порядка 16MB – 32MB, что критически важно для тяжелых расчетов 1С, создающих временные таблицы.maintenance_work_mem — объем памяти для административных задач (индексация, очистка VACUUM). Рекомендуется установить значение от 128MB до 512MB.После изменения параметров в конфигурационном файле postgresql.conf не забудьте перезапустить службу СУБД для применения настроек.
Регулярно обновляйте платформу 1С и используемую СУБД PostgreSQL до рекомендованных и протестированных релизов. Это позволит вам защитить бизнес-данные от внезапных сбоев планировщика и обеспечит стабильную работу пользователей в расчетный период.