Jump to content

# pacman (Русский)/Restore local database (Русский)

7 languages

- English
- Español
- Français
- Magyar
- 日本語
- Português
- 中文（简体）

From ArchWiki
< Pacman (Русский)

Состояние перевода: На этой странице представлен перевод статьи pacman/Restore local database. Дата последней синхронизации: 30 апреля 2024. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Несколько признаков необходимости восстановления локальной базы данных pacman:

- Команда `pacman -Q` ничего не выводит, а `pacman -Syu` ошибочно сообщает, что система обновлена.
- При попытке установить пакет с помощью `pacman -S пакет` выводится список уже удовлетворённых зависимостей.

Скорее всего, база данных pacman с установленными пакетами (`/var/lib/pacman/local`) была повреждена или удалена. Хотя это и серьёзная проблема, базу данных можно восстановить приведёнными ниже инструкциями.

Для начала убедитесь, что в системе присутствует лог-файл pacman:

    $ ls /var/log/pacman.log

Если же файл отсутствует, воспользоваться данным методом не получится. В таком случае попробуйте воспользоваться скриптом обнаружения пакетов от Xyne, а если он не поможет, скорее всего, придётся переустановить систему.

## Создание списка пакетов для восстановления

Важно: Прежде чем продолжить, удалите пакеты для других архитектур, если они по какой-либо причине содержатся в кеше pacman или целевом каталоге для пакетов makepkg.

Установите пакет pacman-contrib, чтобы получить утилиту paclog-pkglist.

Создайте скрипт фильтрации логов и сделайте его исполняемым:

    pacrecover

    #!/bin/bash -e

    # загружаем настройки makepkg
    . /etc/makepkg.conf

    # определяем расположение кеша pacman (по умолчанию /var/cache/pacman/pkg) и удаляем префикс через sed
    PKGCACHE=$( (grep -m 1 '^CacheDir' /etc/pacman.conf || echo 'CacheDir = /var/cache/pacman/pkg') | sed 's/CacheDir = //')

    # каталоги, в которых будем искать пакеты
    pkgdirs=("$@" "$PKGDEST" "$PKGCACHE")

    # считываем имена и версии пакетов из ввода и собираем паттерн для поиска пакетов
    while read -r -a parampart; do

            # проверяем каждый каталог на наличие пакета
            for pkgdir in "${pkgdirs[@]}"; do

                    # перебираем в каталоге каждый файл, соответствующий паттерну
                    for i in "$pkgdir"/"${parampart[0]}"-"${parampart[1]}"-*.pkg.tar.{xz,zst} ; do

                            # если файл существует, то печатаем успешно найденный пакет и останавливаем проверку
                            [ -f "${i}" ] && { echo "${i}" ; break; };
                    done

                    # Если файл не нашёлся, выводим название пакета в stderr
            done || echo "${parampart[0]}" 1>&2
    done

Запустите скрипт (опционально передав в качестве параметров дополнительные каталоги с пакетами):

    $ paclog-pkglist /var/log/pacman.log | ./pacrecover >files.list 2>pkglist.orig

Будут созданы два файла: `files.list` с файлами пакетов, до сих пор присутствующих в системе, и `pkglist.orig` с пакетами для загрузки. После выполнения следующей команды может проявиться несоответствие между файлами новой и старых версий пакета. Такие несоответствия должны быть исправлены вручную.

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

    $ { cat pkglist.orig; pacman -Slq; } | sort | uniq -d > pkglist

Примечание: Если эта команда завершается с ошибкой `failed to initialise alpm library`, проверьте, существует ли файл `/var/lib/pacman/local/ALPM_DB_VERSION`. Если же он отсутствует, выполните `pacman-db-upgrade` от имени суперпользователя, после чего также запустив `pacman -Sy` и повторив предыдущую команду.

Проверьте список на отсутствие важных пакетов из группы base и добавьте их:

    $ comm -23 <({ echo base ; expac -l '\n' '%E' base; } | sort) pkglist.orig >> pkglist

Продолжите, когда содержание обеих файлов будет удовлетворительным, так как они используются для восстановления базы данных pacman (`/var/lib/pacman/local/`).

## Восстановление

Объявите в bash функцию восстановления:

     recovery-pacman() {
        pacman "$@"  \
        --log /dev/null   \
        --noscriptlet     \
        --dbonly          \
        --overwrite "*"   \
        --nodeps          \
        --needed
    }

Опция `--log /dev/null` предотвратит засорение лога pacman ненужными сообщениями, `--needed` сэкономит время, пропуская уже присутствующие в базе пакеты, `--nodeps` позволит устанавливать пакеты из кэша, даже если им нужны пакеты-зависимости более новых версий. Остальные параметры позволяют pacman работать с файловой системой без прав чтения или записи.

Заполните базу синхронизации:

    # pacman -Sy

Начните генерировать базу данных, установив локально доступные пакеты из файла `files.list`:

    # recovery-pacman -U $(< files.list)

Установите оставшиеся пакеты из файла `pkglist`:

    # recovery-pacman -S $(< pkglist)

Обновите локальную базу данных, чтобы пакеты, которые не требуются каким-либо другим пакетам, были помечены как установленные явно, а все остальные считались зависимостями. В будущем придётся быть более осторожным при удалении пакетов, но это лучшее решение из возможных, когда оригинальная база данных была утрачена.

    # pacman -D --asdeps $(pacman -Qq)
    # pacman -D --asexplicit $(pacman -Qtq)

Проверьте установленные пакеты на наличие повреждений:

    # pacman -Qk

При желании можно также выполнить поиск файлов, не принадлежащих ни одному пакету.

Наконец, обновите все пакеты:

    # pacman -Su

Category:

- Package manager (Русский)