При администрировании крупных баз данных на платформе 1С:Предприятие 8, работающих под управлением СУБД PostgreSQL, системные администраторы нередко сталкиваются со специфическими ошибками планировщика запросов. Одной из самых коварных является ошибка вида variable not found in subplan target lists (переменная не найдена в целевых списках подпланов). Она может возникать внезапно, блокировать работу отдельных пользователей или целых отделов, а стандартное тестирование и исправление (ТИИ) базы данных при этом не выявляет никаких повреждений структуры.
В этой статье мы подробно разберем природу возникновения данной проблемы, выясним, почему она чаще всего проявляется в конфигурациях на обычных формах (таких как УправлениеТорговлей редакции 10.3), и рассмотрим пошаговые методы её устранения без радикального перехода на дорогостоящий MS SQL Server.
Рассматриваемый сбой не связан с физическим повреждением таблиц базы данных 1С. Это внутренняя логическая ошибка оптимизатора запросов самой СУБД PostgreSQL. Она происходит в момент, когда планировщик пытается построить оптимальный план выполнения (Execution Plan) для слишком сложного SQL-запроса, транслируемого платформой 1С.
Платформа 1С генерирует SQL-запросы динамически. В конфигурации УправлениеТорговлей (особенно при формировании сложных отчетов, работе динамических списков с наложенными отборами или при использовании механизмов RLS — разграничения прав на уровне записей) итоговый SQL-текст может содержать:
UNION и UNION ALL (объединения таблиц).CASE WHEN (выражения выбора) внутри агрегатных функций.LEFT JOIN) с виртуальными таблицами итогов и срезов.Когда количество соединяемых таблиц превышает определенный порог, планировщик PostgreSQL пытается оптимизировать порядок соединений, используя алгоритмы генетического поиска (GEQO) или стандартный перебор. В некоторых версиях PostgreSQL (особенно ветках 10.x, 11.x и 12.x) в алгоритме оптимизатора присутствует баг, из-за которого при перестроении дерева подзапросов теряются ссылки на исходные переменные. СУБД аварийно завершает сессию и выдает ошибку variable not found in subplan target lists.
Интересной особенностью является то, что ошибка может возникать у одного пользователя (например, у которого установлены специфические отборы в списке номенклатуры или отчетах) и полностью отсутствовать у другого, работающего под той же учетной записью, но с иными настройками интерфейса.
Наиболее быстрым и эффективным способом решения проблемы без остановки работы предприятия является корректировка конфигурационного файла СУБД postgresql.conf. Нам необходимо отрегулировать поведение планировщика при анализе сложных соединений.
По умолчанию PostgreSQL пытается оптимизировать порядок связывания таблиц в запросе. Параметры join_collapse_limit и from_collapse_limit указывают СУБД, до какого количества соединений планировщик должен пытаться «схлопывать» явные конструкции JOIN и подзапросы во FROM в единый плоский список для поиска лучшего плана.
Если мы установим эти параметры в значение 1, мы заставим СУБД соединять таблицы строго в том порядке, который указан в сгенерированном платформой 1С запросе. Это мгновенно решает проблему с ошибкой, так как планировщик перестает перестраивать дерево подзапросов.
Однако установка лимита в значение 1 имеет существенный недостаток: производительность тяжелых отчетов может серьезно снизиться, так как 1С не всегда генерирует запросы с оптимальной последовательностью таблиц. Поэтому рекомендуется использовать сбалансированные значения.
Разберем по шагам процесс изменения настроек:
C:\Program Files\PostgreSQL\...\data\).postgresql.conf.join_collapse_limit и from_collapse_limit. Если они закомментированы символом #, раскомментируйте их.8 или 10. Если ошибка сохраняется, временно установите значение 1 для проверки работоспособности, а в дальнейшем постарайтесь поднять его до стабильного максимума (обычно от 8 до 12).Пример настройки параметров в конфигурационном файле:
# Настройки оптимизатора запросов для 1С
join_collapse_limit = 8
from_collapse_limit = 8
geqo_threshold = 12
После сохранения изменений необходимо перезапустить службу СУБД PostgreSQL или выполнить команду перезагрузки конфигурации (pg_ctl reload).
Поскольку ошибка часто завязана на конкретные сохраненные настройки отчетов и динамических списков отдельных пользователей, обязательным шагом является очистка локального кэша 1С на клиентских ПК и на сервере приложений.
При аварийных завершениях работы или динамических обновлениях конфигурации кэш метаданных может рассинхронизироваться. Платформа начинает транслировать СУБД неактуальные структуры запросов, что провоцирует сбои планировщика.
Для очистки кэша выполните следующие действия:
%userprofile%\AppData\Local\1C\1cv8\%userprofile%\AppData\Roaming\1C\1cv8\ascii-uuid каталоги).Если ошибка воспроизводится под конкретным пользователем внутри самой базы данных (например, при открытии журнала документов), сбросьте его личные настройки через режим «Предприятие»: меню Сервис — Настройки пользователя — Очистить сохраненные настройки.
Использование «ванильной» (стандартной) версии PostgreSQL, скачанной с официального глобального сайта, крайне не рекомендуется для работы с «1С:Предприятием». Платформа 1С использует специфические типы данных и механизмы работы с блокировками, под которые СУБД должна быть адаптирована.
Если вы столкнулись с ошибками оптимизатора, проанализируйте текущую версию СУБД:
subplan target lists) в сервисных обновлениях.8.3.18) не рекомендуется использовать PostgreSQL 12 и выше, так как старые механизмы генерации запросов платформы могут конфликтовать с обновленным парсером СУБД.Планировщик PostgreSQL принимает решения о порядке соединения таблиц на основе внутренней статистики распределения данных. Если статистика устарела, оптимизатор может построить некорректный или избыточно сложный план, который приведет к аварийной ошибке.
Для предотвращения подобных ситуаций необходимо настроить регулярные регламентные операции обслуживания баз данных непосредственно в СУБД PostgreSQL. Проанализируем настройки автовакуума (Autovacuum) и сбора статистики:
postgresql.conf включен демон автовакуума:
autovacuum = on
track_counts = on
ANALYZE (или VACUUM ANALYZE) во время минимальной загрузки сервера. Это заставит СУБД актуализировать сведения о распределении ключей в таблицах, и планировщик сможет строить корректные планы выполнения без ухода в бесконечную рекурсию.Соблюдение этих простых рекомендаций по конфигурированию PostgreSQL позволит вам обеспечить стабильную и быструю работу конфигураций 1С любой сложности без необходимости покупки лицензий на коммерческие СУБД.