Как найти все отсутствующие файлы базы данных 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 для очистки системного каталога.

    Часто задаваемые вопросы