Что делать, если удалили pg_wal на работающем сервере PostgreSQL
База данных - Администрирование СУБД
Определённый тип ИТ-катастроф развивается по драматическому сценарию без всякого злого умысла: вредителей нет, хакерской атаки не было, а предприятие всё равно встаёт колом. В центре этой истории — изолированный кластер PostgreSQL и 2,5 терабайта производственных баз 1С. Для крупного бизнеса падение такого контура означает мгновенный паралич: встают конвейеры на заводе, замирают отгрузки на складах, блокируются кассы в розничной сети, а каждый час простоя оборачивается прямыми убытками.
Причиной ночной аварии стала одна роковая, но пугающе логичная с точки зрения обычного сисадмина идея: очистить быстрорастущий каталог на диске из-за нехватки свободного места. Опытные специалисты хотели спасти ситуацию привычными инструментами ОС, но неосознанно выстрелили базе данных в голову — в упор.
Изолированный узловой кластер и выстрел из лучших побуждений
На одиночном сервере PostgreSQL 15 (бесплатная сборка от Postgres Professional для 1С) крутились десятки баз данных общим объёмом 2,5 ТБ, причём более десяти из них находились под постоянной боевой нагрузкой. Система стабильно работала более трёх лет по принципу «работает — не трогай»: без настроенного резервного копирования, без WAL-архивирования и без выделенного администратора баз данных (DBA). И это не уникальная халатность, а типичная реальность рынка: квалифицированных DBA мало, стоят они дорого, поэтому обслуживание СУБД почти всегда ложится на плечи штатных Linux-администраторов или специалистов по 1С.
Внезапно потребовалось срочно развернуть ещё одну крупную базу с помощью многопоточной утилиты от 1С. Скрытая мина замедленного действия таилась в устройстве хранилища: диск виртуальной машины работал по принципу copy-on-write (тонкое выделение ресурсов) с динамическим объёмом, превышающим реальные физические возможности хранилища. Внутри гостевой ОС свободного места было в избытке, но физический файл диска на хосте упёрся в потолок.
Когда посыпались критические алерты о переполнении хранилища, времени на академические размышления не было. В идеальном мире следовало заглянуть во внутренний мониторинг СУБД, изучить логи, выполнить чекпойнт и штатно остановить развёртывание. Однако под давлением бизнеса и шквала уведомлений у дежурных сработал безотказный рефлекс Linux-администратора: стандартными утилитами ОС они нашли самую активно пухнущую директорию и удалили её содержимое прямо на живом сервере, пока утилита продолжала заливать базу. По злой иронии этой директорией оказался pg_wal — каталог журналов предзаписи, на котором держится вся целостность PostgreSQL. Стремясь как можно быстрее потушить пожар, администраторы своими руками уничтожили фундамент работающей базы.
Однако очистка не помогла: алерты с гипервизора продолжали идти (удаление файлов внутри гостевой ОС не сжимает динамический диск хоста мгновенно, к тому же открытые процессом файловые дескрипторы продолжают удерживать место). Чтобы остановить деградацию и спокойно разобраться в происходящем, специалисты решили погасить сервис. Поскольку с Linux они были на «ты», а тонкостей работы СУБД не знали, процесс остановили не штатными средствами базы, а бескомпромиссной системной командой kill -9. Естественно, после удаления pg_wal и жёсткого обрыва записи СУБД отказалась запускаться. Производство встало.
Применение pg_resetwal, тупик для интеграторов и спасительный crash_info
Чтобы хоть как-то поднять сервер, выполнили команду pg_resetwal. Эта утилита сбрасывает состояние журнала предзаписи и заставляет СУБД стартовать в обход штатного восстановления, но ценой разрушения согласованности данных.
После сброса сервер СУБД запустился, однако платформа 1С подключиться к нему не смогла. Ни собственными силами, ни с помощью подрядчиков по сопровождению 1С решить проблему не удалось. Задача состояла уже не в восстановлении работы платформы, а в извлечении повреждённых данных, для этого потребовалась экспертиза на уровне ядра PostgreSQL. Проверка через прямой SQL-клиент (pgAdmin) показала мистическую картину: простейший запрос SELECT 1 проходит мгновенно, а любая реальная операция намертво вешает бэкенд. Все доступные способы диагностики перепробовали, но безрезультатно: казалось невозможным найти концы на изолированном контуре без прямого доступа к консоли и отладчикам (gdb, strace).
(Здесь стоит передать мысленный привет компаниям, оставшимся на проприетарных зарубежных СУБД вроде MS SQL: окажись на месте этой базы «коробка» ушедшего вендора, история тут бы и закончилась — копаться в закрытом ядре просто некому).
Сам по себе запуск СУБД ещё не означал восстановления её работоспособности. Теперь повреждённый кластер рассматривали только как источник данных: нужно было получить к ним доступ, выгрузить всё, что удастся прочитать, и восстановить рабочую систему на новом кластере.
Ситуацию спасло то, что даже бесплатная сборка для 1С была продуктом Postgres Professional, а к разбору инцидента подключились инженеры самого вендора. В сборку компании встроен собственный механизм низкоуровневой диагностики — crash_info, способный выгружать внутреннее состояние серверного процесса без внешних отладчиков. Отправив зависшему процессу специальный сигнал SIGUSR1 (signal 40), специалисты получили дамп стека вызовов и наконец увидели то, что не показывал ни один стандартный инструмент.
Анализ стека выявил, что бэкенд бесконечно крутится в функции _btmoveright, пытаясь обойти дерево B-tree индекса. Принудительное отключение индексных сканирований (SET enable_indexscan TO off;) не помогло. Детальный разбор запроса показал, что зависание происходит при обращении к системным каталогам самой СУБД (pg_class, pg_namespace, pg_attribute). Картина сложилась: сброс WAL через pg_resetwal оставил в неконсистентном состоянии системные индексы, и любая попытка прочитать метаданные таблиц отправляла процесс в бесконечный цикл.
Чтобы обойти ловушку, задействовали специальный параметр PostgreSQL ignore_system_indexes=on, который заставляет СУБД читать системные таблицы последовательно, в обход повреждённых индексов. База наконец начала отдавать данные.
Извлечение информации и переписывание pg_dump «на живую»
Читать таблицы стало возможно, но требовалось эвакуировать их на чистый сервер через pg_dump. И тут возник новый барьер: даже с ключом --data-only (выгрузка только данных без схемы) штатный pg_dump всё равно вызывал внутреннюю функцию pg_get_indexdef(), пытался собрать определения индексов и намертво зависал на битом системном каталоге.
В этот момент проявилась фундаментальная разница между обычными консультантами и разработчиками СУБД. Обладая глубокой экспертизой в исходном коде PostgreSQL, инженеры Postgres Pro прямо в разгар инцидента написали и собрали кастомный патч для pg_dump: теперь при наличии флага --data-only сбор метаданных об индексах полностью отсекался. Только благодаря тому, что вендор смог на лету переписать системную утилиту под конкретную аварию, процесс выгрузки сдвинулся с мёртвой точки.
Дальнейшая реанимация шла буквально по крупицам:
-
Запуск выгрузки базы пропатченной утилитой.
-
Аварийная остановка при встрече с физически разрушенным блоком данных.
-
Исключение битой таблицы из общего потока или ювелирный поиск повреждённых строк методом дихотомии (делением диапазона OID / Primary Key пополам).
-
Перенос уцелевших данных на новый исправный кластер через механизм внешних таблиц (FDW).
Основную рабочую базу удалось поднять за 24 часа непрерывной ночной гонки, только после этого предприятие смогло возобновить работу. Полное вызволение остальных баз заняло около месяца кропотливого труда. Главным чудом стало то, что бизнес потерял лишь документы за последние сутки перед сбоем. Сведения удалось восстановить и перепровести вручную. Вытащить 2,5 ТБ данных после удаления pg_wal и kill -9 без единого бэкапа получилось исключительно за счёт ядерной экспертизы вендора. Однако нужно понимать, что на бесплатных версиях без договора технической поддержки такое спасение является беспрецедентным везением, а не гарантированным регламентом.
Вклад в мировое сообщество PostgreSQL
По следам инцидента инженеры решили проверить, насколько сильно штатный pg_dump --data-only тормозит при включённом ignore_system_indexes даже на исправной базе. На синтетическом стенде из 15 000 таблиц (по 5 индексов и 1 строке в каждой) замеры показали:
-
штатный
pg_dump —выгрузка занимает 62 минуты; -
с патчем от инженеров время сокращается до 7 минут.
Результаты и патч передали в международное сообщество разработчиков PostgreSQL (pgsql-hackers / pgsql-bugs). К дискуссии подключился известный контрибьютор Дэвид Роули, который предложил альтернативную оптимизацию самого внутреннего SQL-запроса в pg_dump, ускорившую сбор метаданных в 3,5 раза без изменения логики флагов утилиты. Так реальная боевая боль легла в основу улучшения глобального PostgreSQL.
Технический регламент и цена спокойного сна
1. Как следовало действовать при резком росте pg_wal и нехватке места
Главная техническая ошибка аварии — попытка лечить симптомы на уровне ОС вслепую, в отрыве от архитектуры СУБД. Правильный алгоритм при подобных инцидентах выглядит так:
-
Диагностировать нагрузку внутри базы. Через представления
pg_stat_activityиpg_stat_bgwriter(а также серверный лог) увидеть лавину пишущих транзакций от утилиты 1С и понять, что механизм контрольных точек (checkpoint) не успевает ротировать журналы. -
Остановить источник трафика и штатно погасить СУБД. Прервать работу внешней утилиты загрузки, после чего выполнить команду
CHECKPOINT;(чтобы база сама безопасно очистила старые сегменты WAL) либо остановить сервис штатной командойpg_ctl stop -m fast(илиsystemctl stop). В этом режиме PostgreSQL корректно прервёт сессии, сбросит буферы на диск и закроет файлы без повреждения структур. -
Решать проблему места на уровне гипервизора. На динамических дисках (copy-on-write) удаление файлов внутри гостевой ОС без
fstrimне возвращает место хосту. Расширять пул хранения или мигрировать соседние ВМ необходимо непосредственно на уровне гипервизора.
2. Архитектурные и управленческие уроки
-
Сквозной мониторинг на трёх этажах. Контролировать только гостевую ОС при тонких дисках бесполезно. Мониторинг обязан видеть реальный остаток пула на гипервизоре, состояние файловой системы внутри ВМ и внутренние метрики СУБД (темп генерации WAL, длительность чекпойнтов, долгие транзакции).
-
Никакого ручного вмешательства в
pg_walи трезвый взгляд наpg_resetwal. Удаление файлов из рабочих каталогов СУБД на живом сервере равносильно уничтожению базы. В свою очередь,pg_resetwal— это не кнопка «починить», а хирургический скальпель крайней необходимости для однократного старта и немедленной эвакуации данных на чистый кластер. -
Наличие встроенных инструментов вендора решает исход аварии. Без механизма
crash_info, встроенного в сборку Postgres Pro, локализовать зацикливание на системных индексах в закрытом контуре было бы невозможно.
Но главный вывод этой истории лежит за пределами командной строки.
Для системного администратора работа с критичной базой 1С без бэкапов и вендорской поддержки — это хождение по минному полю. Достаточно один раз в три часа ночи под давлением руководства нажать привычную кнопку в консоли, чтобы утром оказаться крайним за остановившийся завод и провести следующий месяц без сна, вручную перебирая битые блоки.
Для владельца бизнеса и ИТ-директора этот кейс — наглядная математика рисков. Сутки или двое простоя производства или сети магазинов стоят несоизмеримо дороже, чем коммерческая СУБД. Переход на коммерческую редакцию Postgres Pro Enterprise для 1С с официальной технической поддержкой и современными средствами управления вроде PPEM (Postgres Pro Enterprise Manager) снимает проблему нехватки узких специалистов: настроить регулярное резервное копирование, архивацию WAL и прозрачный мониторинг там можно буквально по кнопке в графическом интерфейсе. А если нештатная ситуация всё-таки случится, за спиной ваших администраторов с первой минуты будут стоять разработчики ядра СУБД, для которых спасение вашей базы — не счастливая случайность, а прямая работа по SLA.
Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.