Как найти все отсутствующие файлы базы данных PostgreSQL после неудачного восстановления
Ошибка ERROR: could not open file 'base/121622383/622439194': No such file or directory часто возникает после развёртывания повреждённого или неполного бекапа. Это значит, что PostgreSQL не может найти один из файлов таблицы или индекса. Чтобы оценить масштаб проблемы и найти все отсутствующие объекты сразу, используйте системные каталоги и утилиты.
Причины ошибки и диагностика
Ошибка указывает на то, что в каталоге base/121622383 (где 121622383 - OID базы данных) нет файла с номером 622439194 (relfilenode). Это может произойти из-за:
- Неполного дампа (pg_dump без --blobs или --schema-only)
- Повреждения файловой системы или сбоя при копировании
- Ручного удаления файлов таблиц
Чтобы не проверять каждый файл вручную, используйте запросы к pg_class и pg_ls_dir.
Автоматический поиск отсутствующих файлов
Подключитесь к базе данных (если она ещё отвечает) и выполните следующий SQL-запрос. Он сравнивает список ожидаемых relfilenode с реальными файлами в каталоге:
SELECT n.nspname AS schema_name, c.relname AS table_name, c.relfilenode, c.oid
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r', 'i', 'm', 'S', 't')
AND NOT EXISTS (
SELECT 1 FROM pg_ls_dir('base/' || (SELECT oid::text FROM pg_database WHERE datname = current_database())) AS f
WHERE f = c.relfilenode::text
);Этот запрос покажет все таблицы, индексы, материализованные представления и последовательности, для которых отсутствует файл данных.
Альтернативный метод - скрипт на стороне сервера
Если база данных не запускается, проверьте файловую систему напрямую. Выполните в bash от пользователя postgres:
cd /var/lib/postgresql/16/main/base/121622383
for f in $(ls); do
if [ ! -f "$f" ]; then
echo "Missing: $f"
fi
doneНо этот метод не покажет, какому объекту принадлежит файл. Для полной картины используйте SQL-запрос выше.
Что делать с найденными проблемами
Обнаружив отсутствующие файлы, у вас есть несколько путей:
- Восстановить из резервной копии - пересоздайте дамп с правильными параметрами (pg_dump -Fc --blobs).
- Удалить повреждённые объекты - если таблица не критична, выполните
DROP TABLE .... - Пропустить ошибки - в некоторых версиях PostgreSQL можно временно отключить проверку целостности (не рекомендуется для production).
После исправления не забудьте выполнить VACUUM FULL ANALYZE для очистки системного каталога.