pacman/Restore local database - ArchWiki

Jump to content

# pacman/Restore local database

From ArchWiki
< Pacman

## Symptoms

The local pacman database may need to be restored if:

- `pacman -Q` produces no output, while `pacman -Syu` incorrectly reports that the system is up to date.
- Installing a package with `pacman -S <package>` lists already satisfied dependencies instead of proceeding.

This usually indicates corruption or deletion of `/var/lib/pacman/local`.

## Prerequisites

Check if the pacman log file is present:

    $ ls /var/log/pacman.log

If the log file does not exist, this method cannot be used. Alternatives:

- Xyne's package detection script (may help reconstruct the package list).
- Full system reinstallation, if no other recovery is possible.

## Generating the recovery list

Warning Ensure that cached packages from other architectures are removed before continuing.

Install pacman-contrib to access `paclog-pkglist`.

### Create the recovery script

Save the following script as `pacrecover` and make it executable:

    pacrecover

    #!/bin/bash -e

    # load configuration settings from the makepkg configuration file
    . /etc/makepkg.conf

    # determine the cache directory from pacman configuration, defaulting to /var/cache/pacman/pkg, remove prefix with sed
    PKGCACHE=$( (grep -m 1 '^CacheDir' /etc/pacman.conf || echo 'CacheDir = /var/cache/pacman/pkg') | sed 's/CacheDir = //')

    # define directories to search for package files
    pkgdirs=("$@" "$PKGDEST" "$PKGCACHE")

    # read package name and version from input and construct a search pattern for package files
    while read -r -a parampart; do

            # loop through each directory to search for matching package files
            for pkgdir in "${pkgdirs[@]}"; do

                    # check each file matching the pattern in the current directory
                     for i in "$pkgdir"/"${parampart[0]}"-"${parampart[1]}"-*.pkg.tar.{xz,zst}; do

                            # if a file exists, print its path and stop checking further
                            [ -f "${i}" ] && { echo "${i}" ; break; }
                    done

                    # If no file is found, output the package name to stderr
            done || echo "${parampart[0]}" 1>&2
    done

### Generate package lists

Run:

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

- `files.list` – paths to locally available packages.
- `pkglist.orig` – packages missing from cache (must be downloaded).

Later operation may result in mismatch between files of older versions of package, still present on machine, and files, found in new version. Such mismatches will have to be fixed manually.

Restrict the second list to packages present in repositories:

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

Note If this fails with `failed to initialise alpm library`, check for `/var/lib/pacman/local/ALPM_DB_VERSION`. If missing, run `pacman-db-upgrade` as root, then `pacman -Sy`. Retry afterwards.

Ensure that base packages are included:

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

Proceed once the contents of both lists are satisfactory, since they will be used to restore pacman's installed package database; `/var/lib/pacman/local/`.

## Performing the recovery

Define a helper function:

    recovery-pacman

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

Option meanings:

- `--log /dev/null`: avoids polluting the log.
- `--needed`: skips already installed packages.
- `--nodeps`: allows installation of cached packages with outdated dependencies.
- `--dbonly`, `--overwrite "*"`, `--noscriptlet`: restrict pacman to database reconstruction only.

### Steps

1. Update sync databases:

       # pacman -Sy

2. Install locally available packages:

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

3. Install remaining packages from repositories:

       # recovery-pacman -S $(< pkglist)

4. Recreate explicit/implicit install status:

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

5. (Optional) Verify installation:

       # pacman -Qk

6. (Optional) Identify unowned files: See Pacman/Tips and tricks#Identify files not owned by any package.
7. Update all packages:

       # pacman -Su

## See also

- Pacman
- Pacman/Tips and tricks
- System maintenance

Category:

- Package manager

pacman/Restore local database
Add topic