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

From ArchWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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

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

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

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

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

$ ls /var/log/pacman.log

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

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

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

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

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

pacrecover
#!/bin/bash -e

. /etc/makepkg.conf

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
  pkgname="${parampart[0]}-${parampart[1]}-*.pkg.tar.xz"
  for pkgdir in ${pkgdirs[@]}; do
    pkgpath="$pkgdir"/$pkgname
    [ -f $pkgpath ] && { echo $pkgpath; break; };
  done || echo ${parampart[0]} 1>&2
done

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

$ paclog --pkglist --logfile=/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 <(pacman -Sgq base | sort) pkglist.orig >> pkglist

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

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

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

 recovery-pacman() {
    sudo 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