追記: 2018/4/26
FreeBSDとpkgのバージョンを記載し忘れていました。下記事象が発生したのは、以下のバージョンの組み合わせです。


FreeBSDには、さまざまなソフトウェアを手軽に使えるよう、ビルド済みのバイナリパッケージが用意されています。バイナリパッケージのインストール、更新、および削除にはpkg(8)コマンドを使用します。

また、ソフトウェアをソースコードからビルドしたいユーザ向けには、Portsという仕組みが用意されています。こちらを使う場合は、ビルドするための時間は必要になりますが、ビルドのオプションを自分好みにカスタマイズできるという柔軟性が得られます。

バイナリパッケージを使う場合、インストールされたソフトウェアのカタログはSQLiteデータベースとして管理されており、以下のファイルに格納されています。

上記ファイルはたいへん重要ですので、万が一の破損や操作ミスによる削除などに備えて、一日に一度バックアップが自動で取られるようになっています。

先日、このファイルをあやまって削除してしまいました。少しあせりましたが、バックアップがあることはわかっていましたので、これを使ってさっそく復旧を試みました。以下のコマンドを実行します。

# cd <適当なディレクトリ>
# cp /var/backups/pkg.sql.xz .
# unxz pkg.sql.xz
# pkg backup -r pkg.sql
Restoring database:
Restoring: 100%
pkg: sqlite error while executing backup step in file backup.c:97: not an error
pkg: sqlite error -- (null)

えっ!? これでうまく行くはずなのに、エラーが出てしまいます。エラーメッセージの中に、errornot an errorが混在していて、エラーなのかエラーでないのかわからない…。ここに至って、かなりあせりました。急いで、エラーメッセージをGoogle検索に放り込んでみると、関係ありそうなURLが二つ見つかりました。

URLに記載されている手順にしたがって、再度復旧を試みます。

$ cd <適当なディレクトリ>
$ xzcat /var/backup/pkg.sql.xz | sqlite3 tmp.sqlite
$ sudo cp tmp.sqlite /var/db/pkg/local.sqlite

ほーっ…。なんとか復旧出来ました。参考URLでは、pkg shellを起動して、PRAGMA user_version=30;を実行していますが、この手順は不要でした。

以上、メモとして復旧手順を記録しておきます。

参考文献

  1. SQLite, https://www.sqlite.org/
  2. How to recreate local.sqlite?, https://forums.freebsd.org/threads/how-to-recreate-local-sqlite.49057/
  3. pkg backup broken #1183, https://github.com/freebsd/pkg/issues/1183