2012-02-04 9 views
1

Linux用のデータベースエンジンで作業しています。カーネルへのシステムコールを1回実行して多数のブロックを書き込むことに関する一貫性に関する質問があります。私はO_DIRECTでデバイスを開きます。O_DIRECTで多くのブロックを一貫して書き込む

デバイスは、ハードウェアに応じて、512,2048または4096のブロック単位でデータを書き込みます.1つのシステムコールで512バイトの2ブロックを書き込むとします。ディスクが1ブロックを書き込んだ後、システムが正確にシャットダウンされるとどうなりますか?通常の操作では、write()システムコールは書き込まれたデータのサイズを返します。したがって、2つの値が一致しない場合は比較してエラーを生成できますが、電源がシャットダウンすると複雑になります。カーネルがあなたが指示した順序でデバイスに書き込み要求を送るかもしれないので、さらに複雑です。要求の末尾が頭の前に書かれていて、電源が切れている可能性があります。

データベースエンジンがトランザクションログを書き込むとします。トランザクションは約4096バイトで、エンジンは512バイトの8ブロックを書き込む必要があります。突然電源遮断が発生し、要求の半分しか書かれませんでした。データベースがこれらの問題をどのように処理するか?この問題を回避するには、まずディスク上の別の場所に書き込みたいブロックの量を書き込む必要があります。正しい戻り値を受け取ったら、データを書き込むことができます。次に、確認を受け取った後、書き込みたいブロックがすべて実際に書き込まれたという情報を更新する別の書き込みをディスクに送信する必要があります。したがって、これは3回の書き込み操作を必要とし、カーネルが別のプロセスからのディスクへの書き込みを行っている場合は、3回のシークが発生します。あまりにも効率が悪い。

私は、ディスクへの書き込み操作が1つだけで多くのブロックの一貫した書き込みを実現する方法を探しています。 (1つのwrite()システムコール)これは可能ですか?

+0

停電を検出してサーバーを正常に停止するのに十分なバッテリまたはコンデンサの充電がないのはなぜですか? –

+0

@R ..、実際これは良いアイデアです。 UPSを持っているだけで、補助ディスクブロックをキャッシュし、1回のシークで実際のデータを書き込むことができます。誰にとってもうまくいかないかもしれませんが、緊急時に備えてバックアップを取っている間に、迅速な日々の操作を提供するための良い解決策です。 – Nulik

答えて

0

moduloいくつかのスピードハッキングは、記述した2回の書き込み動作はまさにデータベースの動作です。それはwrite-ahead loggingと呼ばれ、操作によって順番に書き込まれる単一のバッファと、メモリバッファのディスクへの時々のフラッシュ、対応するフラッシュエントリがログに書き込まれます。次に、データベースシステムが実行を開始すると、ディスクにフラッシュされていない可能性があるエントリをログでチェックし、その値がディスクにフラッシュされます(エントリはログに記録されているため)。

これは実際にデータを書き込むよりも実際には効果的です。ログはシーケンシャルファイルなので、データの追加にはシークは必要なく、回転待ち時間のみが必要です。さらに、ログからいつでもデータを回復できるので、データを実際のデータファイルにすぐに書き込む必要はありません。次に、要求が入っていないときは、ディスクにデータをフラッシュし、ログにフラッシュエントリを書き込みます。このように、DBMSが求める唯一の時間は、1)システムが静かな場合、2)修正されたデータを保持するためにDMBSがメモリ不足になった場合です。あなたのマシンに十分なメモリがある限り、ディスクはまったくシークせず、DBMSがビジーでないときに起こります。

-1

システムをシャットダウンする前に、まずデータベースエンジンをシャットダウンする必要があります。エンジンをシャットダウンすると、まずすべての書き込みを終了して同期化(バッファをフラッシュ)し、エンジンを正常に停止させる必要があります。また、システムシャットダウンスクリプトにコマンドを含めて、システムをシャットダウンする前にまずエンジンをシャットダウンすることもできます。

関連する問題