Ext3のコミット間隔を当てにしたアプリケーションは、Ext4でデータロスの恐れあり 92
調整は慎重に 部門より
あるAnonymous Coward 曰く、
4月にリリースされる予定のUbuntu 9.04(開発コード名:Jaunty Jackalope)のオプションで提供されているファイルシステムExt4を使用した場合、Ext3のコミット間隔を当てにしたアプリケーションによってはデータロスが発生する恐れがあるそうだ(本家記事より)。
バグレポートではKDE 4のデスクトップファイルがロードされた後にクラッシュし、KDEコンフィギュレーションなどのデータが全て失われるという状況が報告されている。
Ext4の開発者Ts'o氏によると、Ext4はXFSのように遅延アロケーションが用いられており、新しいデータの書き込みは最大60秒かかることもある。遅延アロケーションはディスク領域の割り当てを効率化し、書き込みパフォーマンスを向上させることが出来るのが利点とされている。KDEやGNOMEのデスクトップアプリケーションはコンフィギュレーションファイルなどの小さなファイルを複数読んだり書き込んだりするが、システムがクラッシュするとExt4ではデータのアロケーションが行われず、ハードディスクに書き込まれることなくファイルが破損してしまう恐れがあるとのこと。
Ts'o氏はバグレポートで回避策を提示しているが、XFSやBtrfでも同様の問題が起きる恐れがあると指摘する。パッチはカーネル2.6.29には間に合わないが、2.6.30のキューに追加されるとのこと。
Ext3ではコミット間隔が5秒であり、またジャーナリング機能はデフォルトで「data=ordered」モードに設定されているが、この動作を当てにしているアプリケーションはExt4ではデータロスが発生する恐れがあるということのようだ。詳細に関してはバグレポート#317781を参照のこと。
Ubuntu関係なくね? (スコア:2, 参考になる)
Ubuntuのext4でのみ問題が起こるようにも読める文章ですが、
カーネルの問題であって基本的にディストリビューションは関係ないですよね?
(もちろん独自にパッチをバックポート、とかはあるでしょうが)
本家記事は元のバグレポートがUbuntuに対してなされてるのがわかるので意味が通るんですが
こっちでは何が何やら、ミスリードチックです。
Re: (スコア:0)
Ext4の問題でも、Ext3のコミット間隔を当てにしたアプリケーションの問題でもなく、Linuxカーネルの問題……ってことですよね?
何のことなのか訳分からなくてLinux環境ではファイルシステムを意識してソフト開発しないといけないのかなんて思ってました。
Re: Ubuntu関係なくね? (スコア:3, 参考になる)
まとめてみた。
直感:
<落ちたらファイル壊れる部分ここから>
ファイル開く
書き込み
ファイル閉じる
<落ちたらファイル壊れる部分ここまで>
実際:
<落ちたらファイル壊れる部分ここから>
ファイル開く
書き込み
ファイル閉じる
(システムによって実際にファイルが書き込まれる)
<落ちたらファイル壊れる部分ここまで>
そして、ファイル閉じてから実際にファイルが書き込まれるまでの時間が今までは5秒と短かったため、直感に近い状態であった。
ところがext4などの遅延書き込みを採用しているFSでは、書き込まれるまでの時間が長いため、直感とは違う状況になってしまった。
そこで、思う。これはアプリケーションのバグではない。実際にいつファイルを書き込むかを考えるのは、一般にはアプリケーションプログラマの仕事ではない。
それに、そもそもここ [srad.jp]で例示されているプログラムは、Ext3のコミット間隔を当てにしているのではなく、システムがちゃんと落ちずにファイルを書き込んでくれることを当てにしている。
実際に本当に落ちないかは別として、相当な慎重性を要求されるプログラムを除いて、大抵のプログラムはOSが落ちないで働いてくれることを前提としているし、それは別におかしなことではない。
一方、FSはOSに非常に近い部分であり、慎重性も要求される。実際、Linuxでは(FUSEとかめんどいので考えないことにすると)FSはOSに組み込まれている。
なので、今回の問題は、落ちるOSが悪い。が、落ちないOSなんて不可能なので、落ちたときのリスクを考えていないFSが悪い。
ただし、慎重さが要求されており「書き込み前にOSが落ちちゃいました。けど俺が悪いんじゃないよ。テヘッ」が通用しないようなアプリケーションにおいては、その対策をアプリケーション側でも施さないといけない。先ほどの例 [srad.jp]での3をきっちりとする必要があり、1とか2とかやってるんだったら、それはアプリケーションのバグ。
1を聞いて0を知れ!
Re: (スコア:0)
Ext3のコミット間隔を当てにしたアプリケーションの問題ですよ。
Re: (スコア:0)
突然のシステムダウンから復帰したときに、色んなファイルがゼロバイトになる現象のようなんですど、複数のファイルがごっそりゼロバイトになることに未対応であるアプリがあるってだけなんじゃないかと。
Re: Ubuntu関係なくね? (スコア:5, 参考になる)
要はPOSIXで制定されている以上の事を求めるプログラマ多すぎ、というのが結論。
Ext3の挙動が標準であると思い込んでアプリケーション書いていたら、その挙動はExt3固有で POSIXにはそんなこと書いてなかった。
それで、Ext4じゃその挙動が変わっちゃったという話みたい。
Ted Tsoがバグレポートの中 [launchpad.net]で書いていることを引用すると、
データが実際にHDD/SSD等に書き込まれたことを保証するには、1)は論外、2)でも不十分、3)までやらないと駄目だと。
1)の場合は、ファイルを"O_TRUNC"で開いた時点でもとの内容は全て消えちゃってる。 だから、1.b)以降データが実際に 書き込まれるまでクラッシュが発生したら、リブート後そのファイルは空ですよと。
2)の場合は、新しいファイルを開くだけまし。 だけど、2.e)以降データ書き込み以前にクラッシュが発生しちゃうと、 やっぱりリブート後には元のファイルは空になっちゃう。 なぜなら、2.e)で、新しいファイルが元のファイルに上書きされちゃうけど、 この時点で、新しいファイルがディスク に書き込まれている保証はないから。
3)の場合は、3.d)で、データがディスク上に保存されている(もしくは、保存に失敗した)ことが、 fsync()が帰ってきた 時点で保証されると。
バグ報告や本家を読んでもイマイチ分からないのですが、逆にコミット間隔を当てにするにはどういったコードを書けば良いのでしょうね。
5秒間隔のコミットに依存したプログラムというのは上記の1)と2)。
Ext3においては、コミット間隔が短かったのでクラッシュした際のデータロスとかが比較的少かった。
だけど、Ext4では、そのコミット間隔の長さに由来して、今迄存在したけど顕在化しなかったこの問題が 浮上したと。
今回、KDEとGNOMEのドットファイル等でこの問題が発覚した理由は、 アプリケーションがこれらのファイルを 比較的高頻度で1)や2)の手法を使って書き変えているから。
んで、ディスクへの書き込みを保証しなくてはいけないデータにはfsync()か fdatasync()を 使えとのこと。
大量のfsync()に伴うパフォーマンスの減退がいやならば、sqliteとか使って纏めて 書き込めよっていうのがTed Tsoのお勧め。
複数のファイルがごっそりゼロバイトになることに未対応であるアプリがあるってだけなんじゃないかと。
これはまとはずれだと思う。
Re: Ubuntu関係なくね? (スコア:4, 参考になる)
たとえ、ファイル書き込みが完全に同期していたとしても、
この方法だと、write中にクラッシュすればファイルが失われますし、
OSがクラッシュしなくても、該当アプリだけが死んだ場合でもアウト。
でも、世の中には、これを採用しているアプリが結構多いような気がします。最低限でも、
ぐらいはしなきゃダメじゃないかな。3.fは必須。fsync無しなら高レベルI/Oでも可能な範囲だし、アプリそのものの死亡に対してはほぼ安全です。
fとgの間で死んだら困りものですから、読み込み時に「バックアップファイルしか無い時は、バックアップファイルから読み込む」ぐらいのことはした方がいいと思いますが…
私がこの問題にぶち当たったのは mrtg 。
元のログファイルは*.oldという名前で残っているのですが、
先にリネームしてから、新しいログファイルを書き出しているっぽく、
そこで落ちたら0バイトのログファイルが出来ます。
次回実行までにログが消えたのに気がつかなかったら、次の書き出しで、空のログファイルから読み込んで処理が行われて、バックアップファイルも空になってしまいます。
そのせいで何年かため込んだログがばっさり消えてしまいました。
Re: Ubuntu関係なくね? (スコア:1)
ぐらいはしなきゃダメじゃないかな。3.fは必須。fsync無しなら高レベルI/Oでも可能な範囲だし、アプリそのものの死亡に対してはほぼ安全です。 fとgの間で死んだら困りものですから、読み込み時に「バックアップファイルしか無い時は、バックアップファイルから読み込む」ぐらいのことはした方がいいと思いますが…
とかすればokかな。linkできないときは自前でコピー。
yoshfuji
Re: Ubuntu関係なくね? (スコア:2, 参考になる)
3.f) link("~/.kde/foo/bar/baz", "~/.kde/foo/bar/baz~") --- this is optional
とするのが常識じゃないかな? 3.f) と 3.g) の間に割込まれる可能性も考慮しないと!
どこか別の場所で事前にロックとって排他しているのでない場合には、3.b) の
O_TRUNC とかも論外な気がする。NFS まで考えると気休めけど O_EXCL くらいは
つけときたい所。
Re: Ubuntu関係なくね? (スコア:4, 参考になる)
これは何のパッチなのでしょうか?
再び、Ted Ts'o曰く, [launchpad.net]
意訳:(a) ftruncate()されたか"O_TRUNC"で開かれたファイルにwriteし、そのファイルをクローズする際か、(b)まだ、ディスクに書き込まれていないデータを含むファイルを、既に存在するファイルに上書き(rename("foo.new", "foo");上の2.eのケース)する際に、強制的にディスクに書き込むようにする。
基本的には、問題になっているケースに限ってExt3と同様な挙動をするようにする為のパッチとのこと。
なお、大きいファイルやデータベースのファイル等は上記パターンに合致しないのが殆どなので、大体においてExt4のパフォーマンスはそれほど落ちないとか。
安定したシステムにおいて、以上の挙動を無効化する為のマウントオプションも2.6.30向けに準備しているとも。
ちなみに、Ubuntuのカーネルメンテナンスチームメンバらしき人がこのパッチをUbuntu 9.04向けに取り込む予定はない [launchpad.net]と述べている。
Re: Ubuntu関係なくね? (スコア:4, 参考になる)
>> 5秒間隔のコミットに依存したプログラムというのは上記の1)と2)。
>5秒と60秒では、単にリスクの大小の程度問題であって、5秒だとOKだけど60秒だとNGってのは言い過ぎではないかと。
一応、直後に書いたたように、
>> Ext3においては、コミット間隔が短かったのでクラッシュした際のデータロスとかが比較的少かった。
>> だけど、Ext4では、そのコミット間隔の長さに由来して、今迄存在したけど顕在化しなかったこの問題が浮上したと。
なので、この問題自体は重要視されていなかっただけでずっと存在していたんでしょう。
> それに、これはファイルシステム側の問題であって、アプリ側の問題ではないと思う。
この点については、"Not a bug" [slashdot.org]に始まる本家のスレッドで大フレームウォーがあった模様。
一方はPOSIXを盾にこれはアプリケーションのバグと主張し、他方は複雑なファイルシステムのメカニズムをアプリケーションプログラマが知っていることを前提とするのは間違っていると主張。
また、高級言語では、fsync()相当のものがないのもあるよーとも。
Linuxデスクトップユーザの私は、Ext3で現在満足しているので、今回の騒動に関しては人柱乙(だって、Ubuntu 9.04 alphaだし)というのが正直な感想。
Ext4はミッションクリティカルなサーバ等を指向しているのかなあとも思った。
また、btrfs, ZFS, tux3, reiser4等も同様で、今回みたいなことがこれらでもおこらないとの保証はないとのこと。
> それに、遅延書き込みへの防衛としてアプリ側でsyncを頻発したら、遅延書き込みのメリットがなくなって
> しまいますよね。それは、リスクを承知でext4を選択したユーザーにとっても不利益のはず。
これに関しては、再びTed Ts'o [launchpad.net]からですが、
Ext3 data=ordered モードでfsyncが遅かったのは、Ext3特有の問題(全てのデータを一気に書き込む)、Ext4においてはもっとスマートだとのこと
(fsyncされたファイルのみを一気に書き込み、その他のファイルは徐々に書き込む)。よって、Ext4のfsyncはExt3のそれよりも性能がいいとか。
ここら辺のことに関して、私は全然知識がないので有識者の意見が待たれるところ。
Re: Ubuntu関係なくね? (スコア:3, 参考になる)
抜粋解説ありがとうございます、参考になりました。
> 一応、直後に書いたたように、
> >> Ext3においては、コミット間隔が短かったのでクラッシュした際のデータロスとかが比較的少かった。
> >> だけど、Ext4では、そのコミット間隔の長さに由来して、今迄存在したけど顕在化しなかったこの問題が浮上したと。
>
> なので、この問題自体は重要視されていなかっただけでずっと存在していたんでしょう。
おっしゃるとおりですね。
# これを「問題」ととらえるかどうかは、その人の立場/見方によりかわると思いますが、笑。
ここで話題になっている ext3やext4の「コミット間隔」は、ファイルシステム内でデータをバッファから書き出す定期実行間隔のことなので、仮にext4の60秒が5秒になっても、最後のコミットから事故までの間で2次記憶にはデステージされていないデータがある(かもしれない)ことにはかわらないです。
本質的に、ユーザが意図するようにバッファから書き出してもうらうには、a)ユーザが書き出しを指示するか(=fsync/syncなどを発行するか)、a)ユーザがバッファードライトの禁止を指示するか、しかありません。
アプリケーション側でデータ破壊の問題を何も考えず安直にやりたいのであれば、ライトスルーで書く(前述bの方法)のでしょうが、
でもそんなことをしていたら、IO性能は出ないので、「データの意味・整合性を知っている(自ら作り出している)」アプリケーション側で、意識的に整合性のポイントをつくって、使い分ける必要があります(前述aの方法)。
DBなど、性能と信頼性を要求するものは、こういうところまできちんと考えて設計しています(が、現実には、怪しいモノもありますが)。
なお、ext4でコミット間隔を長くした理由には、ext4がエクステント方式を採用していることも関係しています。
ext3などはブロック方式ですが、特に(DBなどの)巨大なファイルを作ったときなどはそのファイルを構成するブロックの間接参照が深くなりIO性能が低下する傾向にあります。
そこでext4はエクステント方式(連続するブロックを開始オフセット/長さで表現するデータ構造)としたことで、これを解決することを目指しています。
(エクステント方式はext4が初めてではありません)。
エクステント方式で性能を出すためには、できるだけ連続したブロックを割り当てることが大切ですが(フラグメンテーションの回避が課題になりますが)、そのためには、できるだけライトデータをバッファして、連続して一気に書き込むことが重要になり(これだけではないですが)、そのため、「意図的に」コミット間隔を長くとっています。
言い換えれば、コミットを(FS内で)乱発するのは、そもそもの設計の狙いに反しているので、そのあたりは慎重に考える必要があるでしょうね。
(ここの設計者の見極めが、今回のTruncate指定でのコミットのパッチにうまく現れていると考えます)
ちなみに、
ファイルを更新中にプロセス終了や電源断でデータ破壊というのは、(バッファが全く関係ないわけではないですが)本質的には別の話ですね。
これはバッファードライトでなくても起きうる話で。
(データの整合性がとれるポイントまでは)データを上書きしないように気をつけよう(CopyOnWriteしよう)、と。
Re: Ubuntu関係なくね? (スコア:2, すばらしい洞察)
ちゃう. データベースやトランザクションモニタを使えってことです.
U*IXシステムの基本的な思想は何においてもベストエフォートなので, 単にシステムコールを呼んだくらいでは業務レベルでの保障は得られず, かなりトリッキーな操作が必要になります. Linuxだとディスクドライバだかブロックデバイス制御だかのレベルで書き込み完了を見ていなくて, ファイルシステム以上では本当にsyncしているかどうか判らないなんて話もありましたし(過去形でいいのかな?). いずれにせよ多くのプログラマにとっては手にあまるレベルなので, 少々大げさに見えても確実さを望むならばデータベースみたいなインフラの上でシステムを構築しないといけなくなります. これは昔の汎用機なんかと同じ考え方ですね.
つまりプログラマおよび使用者にとって取りうる対策は3つで
のいずれかになります. 実際には綺麗に分かれるわけではなくて, それぞれの要求によって落としどころをさぐることになりますけど.
まあ従来の「軽い・速いは正義」という単一的な価値観じゃあ済まなくなって, 「プログラミングが簡易」とか「システムの堅牢性」とかが求められていることが表面化したってのが今回の騒動だと思います.
Re: Ubuntu関係なくね? (スコア:1)
Note that fclose() only flushes the user space buffers provided by the
C library. To ensure that the data is physically stored on disk the
kernel buffers must be flushed too, for example, with sync(2) or
fsync(2).
Re: Ubuntu関係なくね? (スコア:2, 参考になる)
このDISKというのが、どのレベルのモノをさして言っているか/どの切り口から見ているのかにもよりますよね。:D
fsync()はOS内のライトバッファからOS外のデバイスに対する書き出し指示をおこなうものであって、デバイスへ書き込む(書き込み指示を出して完了応答を待ち合わせること)は保証されています。
(これがきちんとできていないのであれば、それは問題です)
ただし、デバイス内でのバッファードライトまで直接禁止するものではないので、仮にデバイス(たとえばHDD)内で揮発性のライトバックキャッシュが構成されていれば、突然の電源断でどうなるかはユーザにはわかりません。
(ドライバレベルでは、これをきちんと指示する仕組みはあります)
なので、エンタプライズ系のシステムでは、HDDのライトバックキャッシュ(WBC)をOFFにして使ったり、UPSをつけてWBC-ONでつかったり、ディスクアレイ装置側にNVRAMを搭載したりして、OS側に「書き込み完了」を返したときには、Stableであることを保証するようにしています。
元のACさんのコメントは、後者(デバイス内でStableなところにきちんと書かれることまで保証されるモノではない)、ということをおっしゃっているのだとおもいますが、ファイルシステムのレイヤの話(ここでのext4のコミットの話)と、デバイスの中の話は、どのレイヤの話を言っているのか、分けて説明しないと、周りの人が、びっくりしちゃいますよー。 :D
Re: (スコア:0)
ひとつにはファイルシステムとカーネルは切っても切れない関係にあること。
んで、Linuxの標準Cライブラリであるglibcなどが狭義のシステムコールを元に書かれている以上、
遅延書き込みなどといったファイルシステム上の現象はglibcなんかの上に書かれた
アプリケーションすべてに影響するってこと。
なのでなにかとLinuxが叩かれる原因になっている遅延書き込みを避けるために
ファイル書き込みを標準Cライブラリのfopen()なんかを使わず
直接システムコールを叩くようなコードが書かれたりしたりして、その場合、
ファイルシステム差を吸収してくれるライブラリを使っていないのだから
ファイルシステムの実装いかんによって動かないコードが出てきたりする。
…てことじゃないのかと。
Re:ハードウェア関係なくね? (スコア:1)
こじつければソフトウェアネタをハードウェア絡みに転用すると仕様がバグになる、という話かも
電源障害でのメインメモリ内容維持は誰も期待してないと思うけど、ストレージへの書き込みは多分完了しているはずだろう、と。そこへ同じコピーオンライト戦略を使うから。ただでさえストレージの Cache の段階でも同じことが起こりうるのに。
なんだっけ (スコア:2)
STOPキーを押してから電源を切ればいいんだっけ。
Re:なんだっけ (スコア:2, おもしろおかしい)
違うよ、リセットボタン押しながら電源を切るんだ。
# 冒険の書を失わないための基本だろ
Re: (スコア:0)
データを保存できるんだよ。
[N][8][0] (スコア:1)
PC-8801FHを持っていましたが、N88-Disk-BASICのIPL部分を書き換えて、
グラフィックVRAMをディスクに保存してから、N88-BASICの方に再度切り替えて立ち上げるようなプログラムを自作していました(アンマウントが必要なN-Disk-BASICは持っていなかったし)。
ディスクを18セクタ/トラックでフォーマットして17/18セクタ目に画像を保存するようにしていたので、
友人には不評でしたが。
Re:なんだっけ (スコア:1)
一つ目の STOP はマシンのために、(以下省略)
閾値は 0 で
問題はファイルシステムではなくクラッシュ (スコア:2)
「停電でもない限り1年でも2年でもクラッシュせずに動き続けるのが当然」くらいの気概をもってほしいものだ.
XFSで経験済み (スコア:1)
普段XFSを使用していますが、何度か経験しています。ThinkPad や Let's Note で何度かサスペンドから復帰できなくなったり USB デバイスドライバがらみでフリーズした際に、ドットファイルの類を喪失していることがたまにありました。多かったのは、Sylpheed の設定ファイル各種と、uim-skk の学習結果。
#それでも XFS の使用をやめなかったのは移行が面倒だったため。
Re:XFSで経験済み (スコア:3, 参考になる)
Ext3と同等のレベルまでは既に直っているとのことです。 [xfs.org]。
XFSのbinary NULL errorというのは有名だったようで。
それで2007年までfixされなかったのはどうよっていうことですけど。
ファイルシステム開発者からしてみれば、XFSの問題も今回の問題もバグではなくて仕様であるということでしょうか。
MS-DOS で万全 (スコア:0)
*BSDで万全 (スコア:0)
クラッシュでスクリーンがブルーに染まることもありません。
Re:*BSDで万全 (スコア:1)
>おかしなOS使わない限り遅延書き込みなんてあぶなっかしい真似なんかしません。
最近は、遅延書き込みしないOSの方が少ないです。
もちろん *BSD も遅延書き込みします。
遅延書き込み後にファイルシステムのメタデータを危険に
さらさないようにジャーナリングしたり、ソフトアップデートしたり
するので、最近はクラッシュ後にファイルシステムが崩壊することは
少なくなりました。
それ以上の保護を望む人は open() 時に同期書き込みを
指示するフラグを設定するか、
書き込み後に、fsync() を呼ぶと良いはずです。
ただし、Linux はファイルシステム側のオプションも
チェックしないと自分の意図と違う動きをするかも。
間違ってたら指摘して下さい > 教祖様
Re: (スコア:0)
あれれー? [wikipedia.org]
Re:逆じゃないの? (スコア:1)
結論としてはfsync()やsync()を呼ぶかどうかの選択権は欲しいです。close()したら勝手にfsync()を呼んだのと同じ結果になる、というのは頂けない。
全部の動作が遅くなりそうです。
> アプリケーションは関係ありません。というか、アプリケーションがOSの
> 動作の詳細を意識しないといけないのなら、それはそのOSがOSとして失格
> ということじゃないですかね。
どうしても安全に保存したいファイルに対してfsync()を呼ぶのは詳細でもなんでもない常識レベルです。
BSDだと普通は update が sync()を定期的に(30秒に1回とか)呼んでいるはずなので通常はそこまでは気にしませんが。
updateの間隔以内に電源ブチ切りしたら(気にしないアプリが多いと思うので)そのファイルが壊れますよ。
> アプリから見れば、データロスしていい
> ファイルなんてひとつもないでしょうから、fsync()を必ずかけるという
> ことになり、そうすると、遅延書き込みの意味がなくなります。
一時ファイルやキャッシュファイルのような用途の場合はクラッシュ時のロストOK(というか仕方なし)なのでfsync()は呼びませんので意味はありますね。
Best regards, でぃーすけ
Re:逆じゃないの? (スコア:2)
そういう場合にはファイルシステムを生のまま使わず、
DBMSなどのロバストなストレージを利用するものだと思うんだけど。
Re:逆じゃないの? (スコア:1)
残念ながらそれは何の解決にもなりません。
DBMSが信頼できると言われているのは redo-log とか言われる機能があるからです。ようするに
a) まず何をするのか記録して
b) 実際に実行する
c) で、終わったことを記録する
という処理をする。a と b で二度ディスクに書いてる。
- a が終わる前の場合、アプリケーションに「終わった」とは返さない。ので、それは無かったことになる。
- a が終わった後、c が完了する前の場合、a に記録されている内容を再実行する。なのでちゃんと実行される。
- c が終わっているならば、そりゃちゃんと終わっています。
というわけ。しかし、問題は「redo-log がちゃんと書き込まれないのにkernelが終わったと返してくる場合」(今回はこれも含む)。
「終わった」というメッセージを受けて、上位アプリケーション(別マシンの場合が多い)は処理を先に進める。
しかし、その直後に DBMS が動いているマシンがダウン。ファイルシステムのバグの性で、redo-log への書き込みが終わっておらず、ログの一部が失われたとしましょう。
DBMS上のTransaction は失われます。しかしアプリケーションは処理を進めている。矛盾が生じるわけです。しかも人知れず。大抵、アプリケーション側はDBMSを信じていますのでろくにログを取っていません。結果、取れたはずの座席予約が消失しているとか、行われたはずの商取引が消滅している、なんてことが起こる。
唯一の救いは、Transaction 単位で失われるので、金銭的授受が中途半端に起こる、などということはない、という点です。結果として:
「あれ? このタイミングで売ったはずのドルが手元に残っている???」
「あれ? 書いたはずの blog が保存されてない???」
のようにユーザーが「???」と感じるだけで、矛盾はなかなか発見されない。確率論的にはヒューマンエラーのほうがよほど確率が高いので。
なので、DBMSの利用はTransaction単位での障害になるという保障はありますが、Transactionが(少なくとも妥当なレベルで)保護される保障には(この場合は)なりません。
fjの教祖様
Re:これはアプリケーション側のバグの話 (スコア:4, 参考になる)
良いポイントですな。
昔は(4.3BSDとかは)、fsync(2) は不要でした。すべてのシステムコール write(2)は「同期書き込み」だった。
なので余りにも遅い、と言うことで libc の fwrite(3) は自前でバッファリングする形で非同期書き込みをしていた。バッファを追い出すには fflush(3) を呼ぶ必要がある。fflush(3)は write(2) を呼び出す。結果として同期書き込みになる。
しかし、その後、kernel 側に非同期書き込みサポートが入った。しかも、そちらがデフォルトになった。
結果、libc の仕様上、fopen(3)されているファイルは「非同期書き込み」でオープンされる。fflush(3)しても fsync(2) は呼ばれず、非同期のままである。
アプリケーションが以上のような歴史的事実を失念していると、データロストが容易に起こる。fopen(3) でファイルを開いたら、fflush(3) 後にファイルデスクリプタを引きずり出して fsync(2) を呼ばなければ、どの OS でもデータロストの可能性が(それもきわめて高い可能性が)存在します。
.
で、その最後の砦が 同期書き込みopen と fsync(2) のはずなのに、それが当てにならないのが Linux。
今まであなたのデータが失われなかったのは by luck でしかございません。
fjの教祖様
Re:これはアプリケーション側のバグの話 (スコア:2, 参考になる)
月刊だった頃の unix Magazine のらすと2号にわたしゃ証拠つきで短期連載をのせていただいているんですが。
# おかげで「ユニマガを潰したのはお前だ」といまだに言われます。はっはっは (|||) そうだったら嫌杉
「証拠を示している人がいない」
のではなく、あなたがものを探していなさすぎるだけです。
fjの教祖様
Re:これはアプリケーション側のバグの話 (スコア:2, 参考になる)
当該記事は読んでいませんが、kernel 2.4.20かそこらの頃にこの問題に気付いて頭を抱えていた記憶が。
あと確か以前kernel.orgのMLでこの手の問題が起きたとき、メンテナ側がそろって「遅延書き込みで良いだろ」って結論に行ったんでしたっけ? そんなこんなを知ってどうすればLinuxで確実な書き込みを行わせられるかを調べたり実験していた記憶が……。(心の中で泣きまくってた)
# 突然の電源断があり得るシステムにLinux載せなきゃいけなかったため
んでこのとき調べた範囲では、BSD系ならsyncかければDisk側のWrite bufferのflushまではやってくれる。Solarisならflushした後のverifyまでやってくれるってんでいっそSolaris使わせてくれと心の中で叫んだような記憶が……。
Re:これはアプリケーション側のバグの話 (スコア:1)
文献を調べるのではなく、自分で実験すれば良いではありませんか。やり方がわからないならまずそれを考えればいい。
実際、実験モデルも立てられないようでは、ググっても何も見つけられないでしょう。検索するべきキーワードを見つけることすらできないでしょうからね。
.
ついでに言うと。。証拠が無い、という人間の大半が日本語しか調べていない、と言うのも特徴ですな。検索するべきキーワードを日本語で引っ張ろうとしている段階で、馬鹿丸出しです。
問題を発見して Linux Community に報告する際の根拠として使うならば、使用言語は絶対英語になります。日本語のページなんぞ作るわけが無い。
「英語で」「実験の際に利用されるであろう用語を」検索すれば、この問題の根拠・証拠なんぞゴロゴロ出てきます。
それを「ない」と言い、「文献を教えろ」と言う段階で、調べていない証拠。正確にはそんなのは調べているうちに入らない程度の行動しかとっていない証拠です。
その態度が無礼以外の何だと?!
fjの教祖様
sync (スコア:0)
Re:sync (スコア:1)
system("sync; sync; sync");でしょ
Re:sync (スコア:1, おもしろおかしい)
最近のコンパイラーは賢いので、その程度では機械語を生成しません。
Re:sync (スコア:1)
加えてsystem(3)もsync(1)もわかってないコメントですね。
判っている人には野暮極まりなく、申し訳ないが… (スコア:4, 参考になる)
わかっていないのは君だ。
最近のコンパイラは恐ろしく、
と書いても、
というコードがアセンブラレベルでは出てくる。
例:
以上を理解したうえで。
と言うコードに対して「あぁ、それは何もしなくてよいのだな。どうせ非同期か同期化なんて、ちゃんと判っているユーザーはいないし」とコンパイラが判断して、何も出力しない、というギャグだ。
fjの教祖様
Re:判っている人には野暮極まりなく、申し訳ないが… (スコア:1, おもしろおかしい)
「機械語を生成しない」に釣られてたわけですね。
例に挙げられているprintf()も機械語(正確にはアセンブリですが)を出力しているわけですし。
最適化で消されるとかの表現だったらギャグと理解できたかもですが。
どう釣られてたかというと「元ACさんが
system("sync; sync; sync");
を
asm("sync; sync; sync");
と誤解しているのでは?」と私が誤解してました。もちろんsyncなどという機械語は存在しませんが。
まさかsystem()呼び出しを消してしまう壮大なギャグだとは…。
Re:判っている人には野暮極まりなく、申し訳ないが… (スコア:1)
ではなくて、文字列最後の"¥n"まできちんと消した上でputsに置き換え
ている、つまり最近のコンパイラだったら"sync;sync;sync"の部分まで
見た上で、その部分も書き換えて最適化しかねない、ということでは。
Re: (スコア:0)
Re: (スコア:0)
Re: (スコア:0)
2回の人はそもそも神に祈ってないので問題ありません。
Re: (スコア:0)
この例だとユーザの設定ファイルだからなあ・・・
面倒なのは、設定が複数のファイルの連携になっている場合で、
片方が壊れて片方が正常に更新された場合に
どうしょうもなくなりますな。
Vistaにトランザクション付きファイルシステムが導入された理由って
この辺だったりするのかな、とか思った。
クラッシュしなければ良い? (スコア:0)
Re:sync信者 (スコア:2)
Re:sync信者 (スコア:1)
今でも信頼できるのは umount/unmount
# ここで失敗しているとさすがに一発でわかる上に証拠も残るので。
で、
# sync;sync;sync;
(ゴリゴリ言うのが収まるのを待って)
# umount /mnt/hogehoge
とやると、どれぐらいディスクIOが発生するか、が普通の人が自分が使っているFSを疑い始める第一歩ではないかと。
# なんで sync;sync;sync ってやっても「ゴッ」としか言わないのに、umount って言うと「ゴリゴリゴリゴリーーー」
# と言うんだ??! FreeBSDの頃は逆だったのにっ?!??! とかね。
今でも sync;sync;sync で「ちゃんと」ディスクがゴリゴリ言うと、心が休まります。
.
どことは言わないが、ある所では、「よし、ちゃんと書けたことを保障するために umount/mount するぞ」を一日一回、本当にやる人たちがいます。サービスが10分ほどとまりますが。
fjの教祖様