Почему после сбоя питания PostgreSQL не запускается в службах Windows, но база 1С при этом работает?

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

Рассмотрим весьма распространенную и на первый взгляд парадоксальную ситуацию, с которой сталкиваются системные администраторы при администрировании связки 1С:Предприятие + PostgreSQL на операционной системе Windows. После внезапного отключения электроэнергии сервер перезагружается, но СУБД PostgreSQL отказывается запускаться привычным образом. При попытке вручную запустить службу в консоли services.msc операционная система мгновенно или с небольшой задержкой выдает стандартное, но малоинформативное сообщение: "Служба была запущена и сразу остановлена".

Однако самое удивительное происходит позже: несмотря на то, что в оснастке Windows служба PostgreSQL по-прежнему имеет статус "Остановлена", пользователи успешно заходят в 1С, проводят документы и база данных полноценно функционирует. Давайте подробно разберем этот феномен, выясним физические причины происходящего, проанализируем логи СУБД и определим, как правильно действовать в таких ситуациях.

Загадка первая: почему служба остановлена, а 1С работает?

Для того чтобы понять природу этого явления, проанализируем взаимодействие диспетчера служб Windows (Service Control Manager, SCM) и процесса СУБД postgres.exe. Когда операционная система пытается запустить службу PostgreSQL, происходит следующее:

  1. Диспетчер служб Windows отправляет процессу PostgreSQL команду на запуск и запускает внутренний таймер ожидания. По умолчанию этот таймаут составляет 30 секунд.
  2. Процесс PostgreSQL, обнаружив, что предыдущая работа была завершена аварийно (вследствие отключения питания), не может сразу перейти в рабочий режим. СУБД обязана запустить процедуру автоматического восстановления согласованности данных — Crash Recovery.
  3. В ходе восстановления PostgreSQL начинает последовательно читать файлы журналов предзаписи (WAL — Write-Ahead Logs) и накатывать незавершенные транзакции на физические файлы таблиц. Этот процесс требует активного чтения и записи на диск. В зависимости от объема базы данных, скорости дисковой подсистемы сервера и объема незаписанных транзакций процесс восстановления может занимать от нескольких минут до нескольких часов.
  4. Все то время, пока идет восстановление, основной процесс PostgreSQL занят и не успевает (и не имеет права) отправить диспетчеру служб Windows сигнал SERVICE_RUNNING.
  5. По истечении 30 секунд диспетчер служб Windows решает, что запускаемый процесс завис или завершился с ошибкой, прекращает ожидание и выводит пользователю сообщение: "Служба была запущена и сразу остановлена". Визуально в консоли служб статус меняется на "Остановлена".
  6. Тем не менее, сам процесс восстановления postgres.exe (а точнее, его фоновый дочерний процесс startup) не завершается. Он продолжает работать в фоновом режиме, используя ресурсы процессора и диска.
  7. Как только процедура автоматического восстановления успешно завершается, PostgreSQL открывает сетевой порт (по умолчанию 5432) и начинает принимать входящие подключения. Кластер 1С:Предприятия мгновенно подключается к базе данных, и пользователи начинают работать. При этом статус службы в Windows так и остается в состоянии "Остановлена", поскольку SCM уже прекратил мониторинг процесса инициализации.

Чтобы операционная система не "теряла" службу во время длительного старта СУБД, мы можем принудительно увеличить время ожидания запуска служб в реестре Windows. Разберем, как это сделать по шагам:

  1. Откройте редактор реестра, нажав комбинацию клавиш Win + R и введя команду regedit.
  2. Перейдите по следующему пути: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control.
  3. Найдите параметр с именем ServicesPipeTimeout. Если такого параметра нет, создайте его (тип DWORD (32-bit)).
  4. Двойным кликом откройте параметр, переключите систему исчисления на Десятичную (Decimal) и задайте значение, равное времени ожидания в миллисекундах. Например, для установки таймаута в 15 минут введите значение 900000.
  5. Перезагрузите сервер для применения изменений.

Загадка вторая: что означают логи "orphan temp table" и таблицы "tt"

При изучении технологического журнала PostgreSQL или системного журнала событий Windows администраторы часто замечают бесконечно повторяющиеся записи следующего вида:

LOG: autovacuum: found orphan temp table "pg_temp_21"."tt5" in database "rzp2"

Давайте проанализируем, почему возникают эти записи и связаны ли они напрямую с аварийным отключением. Платформа 1С:Предприятие при построении сложных запросов (особенно при формировании отчетов, расчете себестоимости или проведении партионного учета) активно задействует механизм временных таблиц. В СУБД PostgreSQL эти таблицы создаются в специальных изолированных схемах, имена которых начинаются с префикса pg_temp_, а сами таблицы получают технические имена вида tt1, tt2, tt5 и так далее.

При нормальном завершении работы сеанса 1С или завершении транзакции эти временные таблицы автоматически уничтожаются СУБД. Но в момент аварийного отключения питания сессии пользователей оборвались некорректно. Временные таблицы физически остались на диске, превратившись в так называемые "сиротские" таблицы (orphan temp tables).

При последующем запуске PostgreSQL фоновый процесс автоочистки autovacuum сканирует системные каталоги, обнаруживает эти устаревшие временные схемы, понимает, что породившие их сессии давно мертвы, и пытается их вычистить. Появление этих сообщений в логах — абсолютно нормальный процесс самоочистки СУБД, свидетельствующий о том, что PostgreSQL успешно справляется с последствиями аварии. Если таких записей слишком много и они забивают лог-файлы, их можно удалить принудительно, выполнив под учетной записью суперпользователя СУБД команду:

DROP SCHEMA pg_temp_21 CASCADE;

Важное предупреждение: выполнять ручное удаление временных схем можно строго в монопольном режиме, когда к базе данных 1С не подключен ни один пользователь, иначе вы рискуете удалить временные таблицы активных транзакций работающих пользователей, что приведет к аварийному завершению их работы.

Как правильно анализировать логи PostgreSQL на Windows

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

В зависимости от версии PostgreSQL и сборки (например, от Postgres Pro или стандартной), файлы логов по умолчанию располагаются в подкаталоге базы данных. Перейдите в каталог установки вашей СУБД, найдите папку с данными (обычно это папка data) и обратите внимание на следующие каталоги:

Откройте последний по дате текстовый файл лога. При восстановлении после сбоя вы должны увидеть примерно следующую картину:


2018-12-10 11:30:02 MSK ВАЖНО: система баз данных запускается
2018-12-10 11:31:06 MSK СООБЩЕНИЕ: система БД была остановлена нештатно; производится автоматическое восстановление
2018-12-10 11:31:06 MSK СООБЩЕНИЕ: запись REDO начинается со смещения C1/3C3B7548
2018-12-10 11:31:06 MSK СООБЩЕНИЕ: запись нулевой длины по смещению C1/3C3C69E0
2018-12-10 11:31:06 MSK СООБЩЕНИЕ: записи REDO обработаны до смещения C1/3C3C69B0
2018-12-10 11:31:06 MSK СООБЩЕНИЕ: последняя завершённая транзакция была выполнена в 2018-12-10 11:27:51
2018-12-10 11:31:06 MSK СООБЩЕНИЕ: система БД готова принимать подключения

Если в логах вы видите непрерывный процесс обработки записей REDO — не мешайте СУБД работать. Наберитесь терпения и подождите завершения процесса восстановления. Любое принудительное завершение процесса postgres.exe в этот момент может безвозвратно разрушить структуру таблиц.

Опасность использования pg_resetwal (pg_resetxlog)

Иногда в процессе аварийного отключения повреждается сам журнал транзакций (WAL), и PostgreSQL физически не может выполнить автоматическое восстановление, циклически падая с критической ошибкой. В интернете часто встречается радикальный совет: воспользоваться системной утилитой pg_resetxlog (в новых версиях СУБД она называется pg_resetwal).

Давайте детально разберем, что делает эта утилита и почему ее использование для баз данных 1С крайне нежелательно. Утилита pg_resetwal принудительно очищает журналы предзаписи и перезаписывает управляющий файл pg_control, фактически очищая всю историю транзакций, которая не успела записаться на жесткий диск. СУБД после этого успешно запустится, однако цена такого запуска огромна:

Если вам все же пришлось прибегнуть к использованию утилиты pg_resetwal из-за отсутствия актуальной резервной копии, обязательно выполните следующие шаги по реанимации информационной базы 1С:

  1. Сразу после успешного запуска PostgreSQL зайдите в базу в режиме Конфигуратора.
  2. Откройте меню Администрирование — Тестирование и исправление....
  3. Установите флаги напротив проверок: "Реиндексация таблиц информационной базы", "Проверка логической целостности", "Проверка ссылочной целостности". В окне выбора действий при наличии битых ссылок укажите "Создавать объекты" или "Очищать ссылки" (в зависимости от вашей политики восстановления).
  4. Запустите процесс проверки. После завершения тестирования обязательно выгрузите информационную базу в файл резервной копии .dt.
  5. Создайте на СУБД новую, абсолютно чистую базу данных и загрузите полученный файл .dt туда. Этот шаг крайне важен, так как он позволяет физически пересоздать структуру таблиц на уровне СУБД и избавиться от возможных скрытых дефектов дисковой разметки таблиц, которые не смогло выявить тестирование конфигуратора.

Рекомендации по предотвращению повреждения СУБД при сбоях питания

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

← На главную