ファイルアクティビティをディスクにフラッシュすることに関するWindowsWin32C++の質問。
ファイルを作成する外部アプリケーション(CreateProcessを使用して実行)があります。つまり、返されるときに、いくつかのコンテンツを含むファイルが作成されます。
続行する前に、プロセスで作成されたファイルが実際にディスクにフラッシュされたことを確認するにはどうすればよいですか?
これは、C ++バッファではなく、実際にディスクをフラッシュすることを意味します(FlushFileBuffersなど)。
私はファイルHANDLEにアクセスできないことを忘れないでください。もちろん、これはすべて外部プロセス内に隠されています。
私は自分のハンドルをファイルに開いてからFlushFileBuffersを使用できると思いますが、これが機能するかどうかは明らかではありません(私のハンドルには実際にフラッシュが必要なものが含まれていないため)。
最後に、これを管理者以外のユーザースペースで実行して、ボリューム全体でFlushFileBuffersを使用できないようにします。
何か案は?
更新:なぜこれが問題だと思うのですか?
私はデータバックアップアプリケーションに取り組んでいます。基本的に、説明されているようにいくつかのファイルを作成する必要があります。次に、内部DBを更新する必要があります(SQLite組み込みDBを使用)。
最近、ブルースクリーン中にデータ破損の問題が発生しました(原因はアプリとは関係ありませんでした)。
私が懸念しているのは、システムクラッシュ時のアプリケーションの整合性です。そして、はい、このアプリはデータバックアップアプリなので、私はこれを気にします。
私が懸念しているユースケースは次のとおりです。
- 小さなデータファイルは、外部プロセスを使用して作成されます。この書き込みは、OSキャッシュでディスクへの書き込みを待機しています。
- DBを更新してコミットします。これはディスクアクティビティです。この書き込みもOSキャッシュで待機しています。
- システム障害が発生します。
私が見ているように、私たちは今、潜在的な競合状態にあります。「1」がフラッシュされ、「2」がフラッシュされない場合は、問題ありません(DBトランザクションがコミットされていないため)。どちらもフラッシュされないか、両方がフラッシュされる場合は、問題ありません。
私が理解しているように、書き込みは非決定論的です。つまり、OSが「2」の前に「1」を書き込むことを保証することを私は知りません。(私が間違っている?)
したがって、「2」がフラッシュされても「1」がフラッシュされない場合は、問題が発生します。
私が観察したのは、DBが正しく更新されたが、ファイルにガベージが含まれていることでした。データの最後の3分の2はバイナリの「ゼロ」でした。さて、ブルースクリーン時にファイル部分をフラッシュしたときの様子はわかりませんが、そのように見えても驚かないでしょう。
これが原因であることを保証できますか?いいえ、これを保証することはできません。私はただ推測しています。ディスク障害またはブルースクリーンの結果として、ファイルが「自然に」破損した可能性があります。
パフォーマンスに関しては、これは私が対処できると私が信じていることです。
たとえば、SQLiteのデフォルトの動作では、トランザクションをコミットするたびに(FlushFileBuffersを使用して)完全なファイルフラッシュを実行します。これを行わないと、システムクラッシュ時に、DBが破損している可能性があることは明らかです。
また、「チェックポイント」でフラッシュするだけで、パフォーマンスの低下を軽減できると思います。たとえば、50個のファイルを書き込み、ロットをフラッシュしてからDBに書き込みます。
これがすべて問題になる可能性はどのくらいありますか?私を殴る。しかし、私のアプリはシステム障害時またはその前後にアーカイブされている可能性があるため、あなたが考える可能性が高くなります。
それが私がこれをしたくない理由を説明することを願っています。