Почему возникает задержка между ПередНачаломРаботыСистемы и ПриНачалеРаботыСистемы в 1С при работе с PostgreSQL?

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

Каждый администратор крупных информационных баз «1С:Предприятие 8» рано или поздно сталкивается с загадочными проблемами производительности при запуске системы. Представьте ситуацию: у вас есть две абсолютно идентичные копии базы данных на одном кластере серверов под управлением PostgreSQL. Одна база запускается за привычные 10–12 секунд, а вторая «зависает» на заставке почти на 30–40 минут.

При этом в отладчике мы четко видим, что процедура ПередНачаломРаботыСистемы() уже успешно завершилась, а клиентский обработчик ПриНачалеРаботыСистемы() еще даже не начинал выполняться. Давайте подробно разберем, что происходит в этот таинственный интервал времени, почему СУБД начинает совершать сотни тысяч операций чтения и как решить эту проблему раз и навсегда без утомительной выгрузки и загрузки базы данных (файла .dt).

Что происходит «между» двумя стартовыми обработчиками?

Многие ошибочно полагают, что между завершением ПередНачаломРаботыСистемы() и стартом ПриНачалеРаботыСистемы() платформа простаивает или просто проверяет лицензии. На самом деле в этот момент платформа «1С:Предприятие» выполняет колоссальный объем скрытой работы по подготовке пользовательского интерфейса. Проанализируем эти процессы по шагам:

  1. Проверка прав доступа и ролей. Платформа считывает ограничения прав доступа (RLS) для текущего пользователя и вычисляет значения функциональных опций. Это необходимо, чтобы понять, какие элементы интерфейса вообще нужно отображать.
  2. Чтение персональных настроек пользователя. Это один из самых «узких» моментов. Платформа обращается к системной таблице настроек (в СУБД это таблица _SystemSettings, также известная как Хранилище системных настроек). Оттуда считываются индивидуальные параметры: настройки динамических списков, размеры и положения ранее открытых окон, история выбора элементов, избранное и персональные панели.
  3. Создание главного окна приложения. До этого момента пользователь видел только статичную картинку заставки. Теперь платформа конструирует графическую оболочку.
  4. Инициализация Начальной страницы (Рабочего стола). Если в конфигурации для пользователя определена начальная страница, платформа начинает создавать формы, расположенные на ней. Для каждой формы на сервере вызывается предопределенная процедура ПриСозданииНаСервере. Если эти формы содержат тяжелые динамические списки, диаграммы, выборки задач, напоминаний или новостей, все соответствующие запросы к базе данных выполняются именно в этот момент — еще до того, как управление вернется на клиентскую сторону в процедуру ПриНачалеРаботыСистемы().

Анатомия проблемы: почему база зависает на полчаса?

Выясним причину, основываясь на данных мониторинга СУБД. Если в «здоровой» базе СУБД считывает около 8 000 блоков данных при старте, а в проблемной — более 300 000 блоков, это явный признак неоптимальной работы с дисковой подсистемой. Почему так происходит?

Основная причина кроется в особенностях архитектуры MVCC (Multi-Version Concurrency Control) в PostgreSQL и поведении системных таблиц «1С»:

Раздувание (Bloat) таблицы настроек. Таблица _systemsettings подвергается постоянным изменениям. Каждый раз, когда пользователь закрывает форму, меняет ширину колонки или выбирает элемент из списка, платформа перезаписывает настройки. В PostgreSQL при изменении строки старая версия физически не удаляется, а помечается как «мертвая». Если встроенная служба очистки (autovacuum) не справляется с нагрузкой, таблица настроек и её индексы раздуваются до гигантских размеров. При старте сеанса СУБД вместо быстрого поиска по индексу начинает выполнять полное сканирование таблицы (Seq Scan), перебирая миллионы «мертвых» строк в поисках актуальных настроек одного пользователя.

Устаревшая статистика планировщика. Если статистика по таблице _systemsettings или таблицам документов, выводимых на начальную страницу, давно не обновлялась, планировщик PostgreSQL выбирает неверный план выполнения запроса. Он считает, что таблица маленькая, и игнорирует индексы, что приводит к многоминутному сканированию диска.

Повреждение индексов СУБД. Локальное повреждение или сильная фрагментация индексов системных таблиц также заставляют PostgreSQL читать избыточные объемы данных с диска.

Выгрузка базы данных в файл .dt и последующая загрузка временно решают проблему только потому, что при загрузке вся структура таблиц создается заново, мертвые строки физически исчезают, а индексы перестраиваются с нуля. Однако это борьба с симптомами, а не с причиной.

Пошаговая диагностика проблемы

Рассмотрим, как локализовать и подтвердить проблему с помощью штатных инструментов администратора.

Шаг 1. Настройка Технологического журнала (ТЖ)

Обычная настройка ТЖ, отслеживающая только системные ошибки или общие процессы, здесь не поможет. Нам нужно увидеть реальные SQL-запросы к СУБД и длительность их выполнения. Для этого отредактируем файл logcfg.xml. Обязательно добавим сбор событий DB и DBMS.

Создадим правильную структуру конфигурационного файла:


<config xmlns="http://v8.1c.ru/v8/tech-log">
    <log location="/1CData/tech_log" history="24">
        <event>
            <eq property="Name" value="DB"/>
            <gt property="Duration" value="100000"/> <!-- Фильтруем запросы длиннее 0.1 сек -->
        </event>
        <event>
            <eq property="Name" value="DBMS"/>
            <gt property="Duration" value="100000"/>
        </event>
        <event>
            <eq property="Name" value="EXCP"/>
        </event>
        <property name="all"/>
    </log>
</config>

После применения этой настройки запустим проблемную базу. В полученных логах ТЖ мы анализируем свойство Duration. Ищем самый длительный запрос — именно он покажет имя таблицы СУБД (например, _systemsettings или _inforgXXXX), на которой спотыкается система.

Шаг 2. Анализ активных процессов в PostgreSQL

В момент, когда запуск системы завис, откроем консоль управления PostgreSQL (pgAdmin или psql) и выполним следующий запрос для мониторинга активных транзакций:


SELECT 
    pid, 
    query, 
    state, 
    age(clock_timestamp(), query_start) AS duration 
FROM pg_stat_activity 
WHERE state <> 'idle' AND query NOT LIKE '%pg_stat_activity%';

Этот запрос наглядно продемонстрирует, какой именно SQL-запрос сейчас выполняется сервером баз данных и сколько времени он уже занимает. Если мы увидим запрос к таблице системных настроек со статусом активности, продолжающийся тысячи секунд, диагноз подтвержден.

Шаг 3. Исключение влияния форм начальной страницы

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

1cv8.exe ENTERPRISE /F "ПутьКБазе" /DisableHomePageForms

Если с этим флагом база запустилась мгновенно, значит, проблема локализована в процедурах ПриСозданииНаСервере() одной из форм начальной страницы (например, вывод новостей, полнотекстовый поиск по всей базе или некорректно построенный динамический список документов).

Как решить проблему без пересоздания базы данных?

Выяснив причину, перейдем к ее устранению непосредственно на уровне СУБД. Нам не нужно монопольно выгружать базу в файл .dt и тратить часы на ее развертывание. Выполним точечное обслуживание проблемной таблицы.

Метод 1. Сжатие и очистка таблицы в СУБД

Если диагностика указала на раздувание системной таблицы настроек _systemsettings, подключимся к базе через pgAdmin под учетной записью суперпользователя СУБД и выполним последовательно три команды:

  1. Физическое сжатие таблицы: VACUUM FULL _systemsettings; Важно: Эта команда заблокирует таблицу _systemsettings на запись, поэтому выполнять ее рекомендуется в период отсутствия активных пользователей в базе. Она полностью перепишет физический файл таблицы на диске, удалив все «мертвые» строки и вернув свободное место операционной системе.
  2. Перестроение индексов: REINDEX TABLE _systemsettings; Эта команда воссоздаст все индексы для таблицы заново, устранив их возможные повреждения и фрагментацию.
  3. Обновление статистики: ANALYZE _systemsettings; Команда принудительно обновит статистические данные о распределении значений в таблице, позволяя планировщику PostgreSQL мгновенно строить оптимальные планы запросов (использовать быстрый Index Scan вместо тяжелого Seq Scan).

Метод 2. Тонкая настройка Autovacuum для баз 1С

Чтобы избежать повторения этой проблемы в будущем, необходимо скорректировать настройки службы автоматической очистки PostgreSQL. В файле конфигурации postgresql.conf установим более агрессивные параметры для обработки быстроменяющихся таблиц:


# Порог срабатывания автовакуума в процентах от изменившихся строк
autovacuum_vacuum_scale_factor = 0.05

# Порог срабатывания обновления статистики в процентах от изменившихся строк
autovacuum_analyze_scale_factor = 0.02

# Минимальное количество изменившихся строк для запуска очистки
autovacuum_vacuum_threshold = 50
autovacuum_analyze_threshold = 50

Такие параметры заставят PostgreSQL гораздо чаще чистить временные и системные таблицы «1С», не допуская их критического раздувания.

Метод 3. Регулярная очистка устаревших настроек в самой 1С

В процессе многолетней эксплуатации базы в таблице настроек накапливаются терабайты мусора от уволившихся сотрудников, старых вариантов отчетов и неиспользуемых оконных привязок. Рекомендуется периодически запускать встроенную обработку «Очистка настроек пользователей» (раздел «Администрирование» — «Настройки пользователей и прав» — «Очистка настроек»). Это позволит уменьшить физический объем хранимых данных и ускорить процедуру их инициализации при старте каждого сеанса.

← На главную