私が管理している FreeBSDサーバーのうち一台のパッケージデータベースが壊れたようで、パッケージメンテナンスがほぼ出来なくなってしまいました。
パッケージをメンテナンスしようと、
pkg upgrade -y
とコマンドを発行すると、trousers という他のパッケージから依存性が高いパッケージで必ず失敗してしまうようになりました。
[23/109] Installing p5-Socket6-0.29... [23/109] Extracting p5-Socket6-0.29: 100% [24/109] Installing trousers-0.3.14_2... pkg: sqlite error while executing iterator in file pkgdb_iterator.c:1035: database disk image is malformed pkg: sqlite error while executing INSERT OR REPLACE INTO files (path, sha256, package_id) VALUES (?1, ?2, ?3) in file pkgdb.c:1791: database disk image is malformed
trousers に依存しないパッケージは個別に pkg upgrade <pkg name> とコマンドを発行することによりメンテナンスできるのですが、依存性があるパッケージはどうしようもありません。
元々は、別のメモで記録した問題が発端です。/var/db/pkg 以下にある、local.sqlite というデータベースファイルが壊れてしまったようです。同ディレクトリ下にある repo-FreeBSD.sqlite というpkgのキャッシュファイルを消して試したのですが、今回は効果がありません。
pkg check コマンドなどを試してみましたが、私の知識では修復はできそうにありませんので、最終手段を取ることにしました。
パッケージデータベースの管理ファイル local.sqlite ファイルを消去します。
これで pkg コマンドはパッケージが何もインストールされていないと認識するようになります。
その後で、事前にメモしておいたインストール済みパッケージを pkg install コマンドで上書きします。コンフィグファイルを含めたファイルはそのまま残っていますので、手間は掛かるものの抜けがなければこれで復活するはず。
ついでにあまり使わなくなったパッケージは入れずに、データベースからは情報を抜くことにしました。
ちょっと面倒だったのが、バイナリーカスタマイズしていたパッケージがあったこと。これに関しては、pkgコマンドは使えないので、/usr/ports 下で make install することになりました。
約1時間かけて修復が完了。
local.sqlite ファイルが malformed となった場合は、どうやって修復すればいいのでしょうね。不完全に修復できるよりは、入れ直す方が安全だとは思うので、修復するべきかどうかは微妙かも。