Linuxで読込中のファイル削除の影響
サーバーアプリケーションでは、特定のファイルに対し、読み書きが同時に発生することがある。同時書き込みを防止するためには書き込みロックを利用したり、書き込み中の読み込みを防止するためには読み込みロックを利用したりする。
しかし、一般的にロックを使用するとロックの取得待ちが発生することになり、環境によってはパフォーマンスの劣化が起きる。パフォーマンス重視の環境なら、できればロックは使用せずにいきたい。
では単純にロックを使用せず、読み込み中にファイルを削除するとどうなるのか?気になったので調べてみた。
関連記事:
実験手順
次の手順で実験を開始した。まず、読み込み側のプログラムread_twiceを準備する。このプログラムは、まずファイルの先頭10バイトを読み込み、Enterキーを押すと最後まで読み込んで画面に表示するというもので、C言語で作成した。ファイルの削除はrmコマンドで行う。テスト対象のファイルはA100.txtで、「A」の連続する100バイトのテキストファイルとする。
手順4の段階で、残りの90バイトが正しく表示されるのか?
実験結果は?
結果は次の通り。「Press enter key:」が表示された時点で、別コンソールからファイルA100.txtを削除したのだが、A100.txtは最後まで読み込むことができた!
ディスクキャッシュやファイルバッファの影響かと思い、 1GBのファイルで再度実験を行ったが、結果は同じ。やはり、オープン中のファイルを削除したとしても、読み込み側の処理には影響は与えないようだ。
まとめ
実験の結果から、今回の環境では次のことが言える。
- ファイルの読み込み中にファイルを削除しても、削除前のデータが正しく読み込まれる
なぜ削除したはずのファイルが読み込めてしまうのか?それは、ファイルの削除を行っても、ファイルシステム上はディレクトリエントリ(ファイル一覧表)から該当ファイルのエントリを削除することしか行わず、ファイルの実体は残されたままだからだ。ファイルを削除する前にファイルをオープンさえしておけば、そのファイルは最後まで読むことができる。
ちなみに今回の話題は、ファイル更新処理のパフォーマンス改善策を検討しているときに疑問となっていた点だった。ファイル更新処理にロックは必須・・・と思っていたが、ファイルシステム上、どの部分が更新されるのかということに注目し、ロックの方針を決めても良さそうだ。
例えば、ファイル名変更・ファイル削除ならディレクトリエントリだけを変更するファイル更新となり、アトミックな操作が保障されているのでロックは不要。ファイル上書きならファイル実体を変更するファイル更新となり、アトミックな操作が保障されないのでロックは必要。ファイル更新の組み合わせによってはロックが必須の場合もあると思うが、できる限りロックする必要がないようにファイル設計しておけば、パフォーマンスの改善が見込めそうだ。
関連記事: