2009-04-01 12 views
20

close()またはfclose()などを使用してファイルを閉じた場合、Linuxはそのファイルが(永続的な)ディスクに書き戻されることを保証しますか?Linuxはclose()の後にファイルの内容がディスクに書き出されることを保証していますか?

close()が0を返してからすぐに電源が落ちた場合、以前に書き込まれたデータは永続性が保証されている、つまり耐久性がありますか?

fsync()システムコールはこの保証を提供します。ファイルを閉じることで十分ですか?

現時点では、何らかの主張をすることができません。


質問2:

close()が暗黙的fsync()を行うならば、ないにそれを伝える方法はありますか?

答えて

30

man 2 close」から:成功したクローズは カーネルは書き込みを延期などのデータが 成功し、ディスクに保存されていることを保証するものではありません

マニュアルページには、データがディスク上にあることを確認したい場合は、fsync()を自分で使用する必要があります。

3

いいえ、保証されません。 OSには独自のキャッシュがあります。クローズアップが本当に保証されるのは、プログラムのバッファがOSにフラッシュされることですが、OSは未書き込みのままです。 Linuxカーネルの世界では、fsyncでさえ少なくともext3ではディスクにフラッシュされることを保証していないので、いくつかの論争があると私は信じています。

+1

fsync()が行うべきことをしなかった場合、それはひどいバグです。 – MarkR

+0

、つまりデータベースの耐久性を完全に破壊します。 – MarkR

+0

私が見てきた論争は、コメントに収まらないものです。私はそれに対する答えを書いています。 –

11

いいえ、近いないは(2)のfsyncを実行しないと、それはそのようにした場合の死に多くのマシンを打者だろう。多くの中間ファイルは作成者によって開閉され、次にコンシューマによって開閉され、その後削除されます。 close(2)がfsync(2)を自動実行した場合、この非常に一般的なシーケンスでディスクに触れる必要があります。代わりに、ディスクは通常タッチされず、ディスクはファイルがそこにあることを決して知らない。

+0

本当ですか?これについての参考資料がありますか? – MarkR

+2

はい。とりわけ、同期が行われていないと言います(2)。ファイルシステムのキャッシュに関するより大きな問題については、HennessyとPattersonの "Quantitative"オペレーティングシステムの教科書のような、OSの現代的なディスクキャッシュをカバーする良いテキストを見てください。 –

+4

でも 'fsync()'は確実ではありません。ディスク制御では、少なくとも少々の時間のデータをキャッシュしている可能性があります。 – vrdhn

0

ドライブ自体もデータをキャッシュすることができるので、Linuxがこれを保証するとは思いません。

+0

しかし、ドライブに指示されていないか、バッテリバックアップされたRAIDコントローラであるため、この保証は原則可能です。 – MarkR

+0

原則として、それは当てはまるかもしれませんが、実際にはそれは確かに定例ではありません。 –

+0

ドライブに問題があります。それで、何かを書いて嘘をついたことを報告できるのであれば、ドライブに問題があります。デバイスドライバがディスクに書き込まれたと確信したら、Linuxはできること全てをやり遂げました。 –

6

いいえ、fclose()はfsync()を意味しません。多くのLinuxファイルシステムは書き込みを遅らせ、それらをバッチアップするため、全体的なパフォーマンスが向上し、おそらくディスクドライブの消耗が減り、ラップトップのバッテリ寿命が向上します。ファイルが閉じられたときにOSがディスクに書き込む必要がある場合、これらの利点の多くは失われます。

Paul Tomblinは彼の答えで論争を述べ、私が見たことを説明することはコメントに合わないだろう。ここに私が聞いたことがあります:

最近の論争はext4の注文です(ext4は普及しているext3 Linuxファイルシステムの後継です)。 LinuxやUnixシステムでは、古いファイルを読み込み、新しいファイルを別の名前で書き出し、新しいファイル名を古い名前に変更することで、重要なファイルを変更することが一般的です。考え方は、システムがある時点で故障しても、新しいものか古いものかを確実に確認することです。残念なことに、ext4は古いものを読み込み、新しいものを古いものに名前を変更して新しいものを書き込むのがうれしいようですが、システムがステップ2と3の間でダウンすると本当の問題になります。

これに対処する標準的な方法はもちろんfsync()ですが、それはパフォーマンスを破壊します。本当の解決策は、ext3を変更してext3の順序を維持することです。ext3の順序付けは、ファイルの書き出しが完了するまでファイルの名前を変更しません。どうやらこれは標準ではカバーされていないので、実装上の問題であり、ext4のQoIは本当に厄介です。fsync()を常に呼び出すことなく新しいバージョンの設定ファイルを確実に書く方法はなく、両方のバージョンを失う危険性があります。

+1

それは私が考えているかもしれません。私は彼らが怒っていたことを正確に怒鳴ったと聞いた人々に尋ねるべきです。 –

+0

これは最近のSlashdotの大きなファイルシステムです。私は、あなたの上司に厄介な辞表を電子メールで送り、あなたのポルノコレクション(/。meme)をあなたのお母さんにヌルポインタの参照解除についてEメールで送ることは、C++システムでも同様に標準に準拠することを提案しました。 –

+1

ext3のdata = orderedオプションのようなものを有効にする新しいバージョンのExt4のオプションがあります:http://thread.gmane.org/gmane.comp.file-systems.ext4/12179 –

8

fsyncは、ファイルがディスク上にあることを保証するものではありません。 OSがファイルシステムにディスクへの変更をフラッシュするよう要求したことを保証するだけです。 _POSIX_SYNCHRONIZED_IOが定義されていない場合はファイルシステムがman 3 fsync

からディスク

には何も記述する必要はありません、文言は、システムからの 期待することができるものをユーザーに伝えるために適合文書に大きく を依存しています。 NULL実装 が許可されることが明示的に意図されています。

幸いにも、Linuxの一般的なファイルシステムはすべて実際に変更をディスクに書き出します。不運にもファイルがディスク上にあることを保証するものではありません。多くのハードドライブには、書き込みバッファリングがオンになっています(したがって、fsyncがフラッシュしない独自のバッファがあります)。バッファーをフラッシュしたことについてはdrives/raid controllers even lie to youです。

1

bug report fcntl(O_SYNC)がLinuxで動作していないことについて、firebird sqlデータベースからも興味があります。

また、あなたが質問する質問は潜在的な問題を意味します。ディスクに書き込むことによって、どういう意味ですか?なぜそれは重要ですか?電源が切れてファイルがドライブにないことが心配ですか?なぜシステムやSAN上でUPSを使用しないのですか?

この場合、ジャーナリングファイルシステムが必要です。メタデータジャーナリングファイルシステムだけでなく、すべてのデータに対してもフルジャーナルが必要です。

その場合でも、O/Sの義務以外にも、most hard disks lie to you about doing an fsync. - fsyncはデータをドライブに送信するだけで、個々のオペレーティングシステムがそのデータをフラッシュするまで待機する方法自分のキャッシュ。

--jeffk ++

2

オープンのマンページは言う:

同期I/O O_SYNCO_DIRECTに加えて使用する必要があります保証します。

その

一般的に、この(O_DIRECT)は性能を低下させるであろう。

一つは、すべての読み取りと書き込みの後にそこのためのI/Oのキャッシュの影響を最小限に抑えるためにそうとしてF_SETFLのfcntlを使用して、このフラグを切り替えることができます。

-3

コンピュータ/ OSに、少なくともこの制約を課すファイルの電源を切っても耐えられるものへの書き込みを保証するフォールトトレラントなファイルシステムがあれば、これは気にする必要はありません。不揮発性のRAMまたは同等のものがある場合は、ディスクである必要はありません。私が薄暗く覚えている過ぎ去った時代のいくつかのメインフレームは、そのような仕組みを持っていて、おそらくそのような保証をしたと思います。

+0

最新のサーバグレードRAIDコントローラこの機能(バッテリーバックアップされたキャッシュ)を持っています。しかし、コントローラへのバスの速度は有限であるため、OSは、アプリケーションが特に要求した場合にデータが「書き込まれる」のを待つだけです。この質問への答えが示された。 – MarkR

関連する問題