Pg_dump это не только ценный бэкап, но и средство диагностики целостности базы — 17 июня 2026 г. в 04:09:33.900
Pg_dump это не только ценный бэкап, но и средство диагностики целостности базы На этой неделе столкнулись с очень интересной проблемой. Проявлялось это так: - 1С практически не шевелится - Если удалось зайти в 1с, то при совершенно разных операциях получаем ошибки СУБД с разным набором таблиц, которые почти ни о чём не говорят, кроме как что-то пошло не так - Нагрузка ЦПУ на сервере PostgreSQL под 100% Запрашиваем список активных сессий на СУБД select * from pg_stat_activity И получаем список транзакций. Которые длятся минуты и десятки минут с текстом: select * from public._scheduledjobs...; и т.д. Попытка завершить транзакции средствами СУБД ни к чему не приводит. Тем временем прод стоит, паника нарастает… Всё это происходит на PostgresPRO Enterprise с встроенным кластером BiHA. Система определяет что мастер не отвечает и перекидывает всю нагрузку на другую ноду кластера – всё совершенно корректно, как доктор прописал! И что мы видим? – Буквально за 10 минут теперь и "новый мастер" так же уходит в нагрузку по ЦПУ в 100%. Снимаем отладочную информацию со всех процессов мастера и «нового» мастера командой kill <pid> -40 для ТехпПоддержки PostgresPro. И хоть я и очень не люблю так делать, но аварийно останавливаем PostgreSQL через kill <pid> -9 и на мастере и на «новом» мастере. Блокируем 1С. Стартуем PostgreSQL. И для быстрой диагностики запускаем vacuum analyze only в несколько потоков на базе. И опять получаем «зависшие» транзакции analyze на разных scheduledjobs… Поясню – analyze читает не все данные в таблице, а только количество строк = 300*default_statistic_target. Обычно default_statistic_target = 100, т.е. мы читаем только 30 000 строк в таблице, и даже при этом уже получаем зависание системы. Вот это уже страшно… Опять снимаем crash_info, рестартуем службу Postgres и начинаем расстраиваться… Всё больше подозрений на битые страницы данных… И тут встаёт вопрос, как быстро проверить все данные в базе? Ответ – pg_dump, ведь по сути это select * по всем таблицам базы и сбор информации о DDL схемах как самих таблиц, так и индексов. Но, база не маленькая и дамп будет формироваться достаточно долго… Вспоминаем что можно вместо сохранения дампа на диск отправить его в «чёрную дыру» /dev/null, но при этом сохранив логи самого процесса дампа. pg_dump -h 127.0.0.1 -p 5432 -U postgres -d ERP> /dev/null 2> dump.log Такой дамп формируется намного быстрее. Запускаем и получаем в логе сообщение: pg_dump: ошибка: ошибка при выполнении запроса: ERROR: index "pg_attribute_relid_attnum_index" contains unexpected zero page at block 2349 ПОДСКАЗКА: Please REINDEX it. Вот это поворот! Что-то не так с данными системной таблицы атрибутов.. Ну чтож, есть подсказка, давайте ей и воспользуемся: REINDEX TABLE pg_catalog.pg_attribute; И после этого опять запускаем analyze, чтобы проверить починилось ли и да, база починилась, analyze прошёл. Запускаем 1С – проверяем, всё работает. Запускаем пользователей и естественно у них «такая же нога, но болит!..», а именно, при различных операциях получаем ошибку СУБД с текстом: ERROR: heap tid from tuple … offset 204 of block 4 in index “pg_namespace_nspname_index”… Запускаем REINDEX INDEX pg_namespace_nspname_index; - ошибка ушла. Причина по которой разрушились системные индексы пока ещё выясняется. ❗Сама история говорит о том, что базу надо периодически регламентно проверять на целостность, а лучше не базу, а весь кластер командой: pg_dumpall -h 127.0.0.1 -p 5432 -U postgres > /dev/null 2> dump.log При этом лог будет пустой, если дамп не обнаружит ошибок. Если же хочется иметь лог всей работы дампа в любом случае, то команда будет такой: pg_dumpall -h 127.0.0.1 -p 5432 -U postgres -v > /dev/null 2> dump.log

