はじめに
Ubuntuにて、以下のようなエラーに遭遇しました。
test@ubuntu:~$ sudo apt update && sudo apt upgrade -y
Reading package lists... Done
E: Could not get lock /var/lib/apt/lists/lock. It is held by process 1232 (apt-get)
N: Be aware that removing the lock file is not a solution and may break your system.
E: Unable to lock directory /var/lib/apt/lists/
ネットで調べていると多くの方が口を揃えて
「lockファイルの削除で解消しました」 とおっしゃっていたので、(調べ方が浅い?)
実際にlockファイルを削除して事なきを得ました。
ただ、本当にlockファイルを削除してよかったのか気になったため、改めて詳しく調べてみることにしました。
概要
E: Could not get lock <ファイルパス> というエラーは、ubuntuでよく目にするエラーです。
これは、システムが同じファイルへのアクセスを必要とする複数のコマンドを実行しようとしたときに発生します。
主に以下の2つのパターンで発生します。
- OS起動直後などに、裏で unattended-upgrades(自動アップデート)や aptd などのシステムプロセスが稼働し、パッケージの整理や更新を行っているため
- 前回のインストール処理(プロセス)が正常に終わらず、中途半端な状態でプロセスが残ってしまっているため
おそらく、1のパターンが多いかと思います。
lockファイルを安易に削除してはいけない理由
チームDpkg よくある質問 このページにこのような記載があります。
dpkg のロック ファイルを削除することは決して正しい解決策ではありません。dpkg はプロセスに紐づけられた領域ロック (既存ファイルに対して) を使用しているため、プロセスが終了または強制終了されるとロックは自動的に解放されます (dpkg 自体がロック ファイルを削除することはありません)。ファイルが存在するからといって、ロックが現在保持されているとは限らず、削除すると dpkg データベースまたはファイルシステムが破損する可能性が非常に高くなります。ロックをオーバーライドする必要がある場合は、ロック ファイルを削除するよりも、実行中のアクティブな dpkg プロセスを強制終了する方が常に望ましいです。dpkg は突然のシステムまたはプロセスのクラッシュや終了に対して耐性を持つように設計されており、それらに起因する問題は修正が必要な深刻な問題とみなされるためです。
ここで言われているように、ファイルが存在している=ロックが保持されている とはならないんですね。
つまり、lockファイルが残っていることは異常でも何でもないことになります。
もし、プロセスがいないのにエラーが出る場合は、lockファイルのせいではなく、まだ見つけていない別のプロセスがどこかでロックしている証拠だとわかります。
対処法
上記2つのサイトがとても参考になりました。
私が実施した順番でまとめます。
気になる方は上記サイトをご確認ください。
プロセスの特定
E: Could not get lock /var/lib/apt/lists/lock. It is held by process 1232 (apt-get)
エラーログの中に、どのプロセスがロックしているか表示されています。そのプロセスの状態を確認しましょう。
psコマンドで、実際にどんなコマンドが実行されているかの確認
ps -fp <PID>
topコマンドで、プロセスが動いているかの確認
top -p <PID>
プロセスが動いている場合
そのまま完了するまで待ちます。
tailコマンドでログを確認することも
プロセスが動いていない場合
(topコマンドで見てもCPUが全く動かず、長時間フリーズしていると判断した場合)
sudo fuser -vki -TERM /var/lib/dpkg/lock /var/lib/dpkg/lock-frontend /var/lib/apt/lists/lock
sudo dpkg --configure --pending
sudo apt install -f
sudo fuser -vki -TERM
これは、現在ロックを保持しているプロセスを検索し、それらの詳細を表示し、強制終了するかを尋ねるコマンドです。
これで終了がうまくいかない場合は、 -KILLオプションを使用します。
-KILLオプションは下記コマンドとほぼ同じものです。PIDがわかっているのであればこちらの方が早いかもです。
kill -9 <PID>
sudo dpkg --configure --pending
これは、未設定(半分インストール状態)のパッケージをすべて設定しなおすコマンド
configure -a とほぼ同じもの。
sudo apt install -f
依存関係の矛盾をなおす
必須ではない
lockファイルを保持しているプロセスの確認
エラーログに出ているプロセスの対処が完了したところで、念のため実施しました。
下記ファイルは、 apt、dpkgの2つのインスタンスが同時に同じファイルを使用することを防ぐために作成されます。
/var/lib/dpkg/lock
/var/lib/dpkg/lock-frontend
/var/lib/apt/lists/lock
/var/cache/apt/archives/lock
sudo lsof <ファイルパス>
何も出力がなければ、そのファイルが何かしらのプロセスで使用されていないことを表します
すべてのファイルパスで実行し、何も出力がなければエラーは出ないはずです。
再起動
それでも解消しなければ再起動します。
ただ、多くのサーバは簡単に再起動できないと思うので、できるサーバのみ実施します。
まとめ
プロセスが完了すれば、lockファイルという「物理的なファイル」が残っていても、中身の「ロック状態」はすでに解除されるため、lockファイルを必ずしも削除する必要は全くないということがわかりました。