連載
» 2003年09月17日 00時00分 公開

Linuxファイルシステム技術解説(4):ext3とトランザクション処理 (1/2)

長い利用実績を誇るext2の互換ファイルシステムext3。このファイルシステムにはどのような特徴があるのか? そしてどのようにジャーナリングを実現しているのか? 今回はext3について解説する。(編集局)

[菅谷みどり,@IT]

 今回からext3、ReiserFS、JFS、XFSについて解説する。これらのファイルシステムはそれぞれ独自の方法で高速化、信頼性/可用性向上を実現するために開発が続けられている。高速化や可用性を実現する方法としては、前回までにB*-Tree、エクステント、ダイナミックiノードを紹介した。また、信頼性を達成する技術としてジャーナリング機能の基本的な仕組みを解説した。

 各ファイルシステムは、それぞれ独自の方法でこれらの技術を取り込んでいる。特にジャーナリング機能は、これから紹介する4ファイルシステムのいずれもが実装している。ただし、ジャーナリングの内容については次の点で違いがある。

  • ジャーナリング対象(データとメタ・データ両方あるいは片方など)
  • ジャーナリング方法(トランザクション処理、I/Oロギング処理など)
  • ジャーナリング実行順序(順序の保証があるか、ないかなど)

ext3の特徴

 ext3は、ext2にジャーナリング機能を付加した互換ファイルシステムである。ext2のクラッシュからの起動があまりにも遅いことを嘆いたDr. Stephen C. Tweedieが最初の開発者で、ext2のコードを新たにext3用に書き直し、ジャーナリング機能を実装した。カーネル2.4からはAndreas DilgerやAndrew Mortonといった開発者も加わり、LVMとの連携などの強化が図られている。ext2との互換性が保たれているので、ext3をアンマウントしてext2としてマウントすることもできる。

 ext3の主なメリットは次のとおりである。

  • クラッシュ時の起動時間の短縮
    ext2とext3がベースとしているブロックアルゴリズムは安定している半面、起動が遅いという問題があった(第2回)。ext3は、ジャーナリング機能を実装することで起動時間の短縮を実現した。
  • 互換性
    ext3とext2は基本構造が同一なので、ext2からext3への変更などを簡単に行うことができる。
  • 性能
    ブロックのアロケーションや基本的なアルゴリズムはext2と同じだが、コードはext2をそのまま利用するのではなく、スクラッチから書き直された。そのため、ext2に比べてエラー処理やロック、ファンクションの実行手順、アトミック操作など、細かい点で改善が見られる。I/Oについても、ディスクへのフラッシュと非同期に行うことで効率の良い書き込みを実現している。

 ただし、ext3はext2におけるブロックアルゴリズムの制約も引き継いでいる。例えば、ext3はブロックベースでディレクトリ内のファイル名をシーケンシャルサーチしている。シーケンシャルサーチはバイナリサーチに比べて性能が劣る。また、エクステント方式に比べて、大規模システムに対する拡張性が低い点などが挙げられる。

ext3のジャーナリング処理

 ext3はジャーナルログの保存のために、デフォルトでルートパーティションに.journalというデータベースを保有している。後で紹介するが、複数のファイルシステムでこのデータベースを共有することもできる。

 ext3のジャーナリング処理は、次の手順で行われる。ファイルシステムに変更が生じると、それをディスクに実際に反映させる前にジャーナルファイルに変更を記録する。ジャーナルファイルに記録された変更は、バッファのフラッシュのタイミングでディスクに反映される。

 ジャーナルファイルにはバッファに入った情報がそろっているので、クラッシュ後の回復時にその情報が利用される。

ジャーナリング処理の実行のタイミング

 ext3のジャーナリングでは、冒頭で述べた「ジャーナリング方法」にある「トランザクション処理」が行われる。これは、不可分な処理(アトミック処理)を1つの「トランザクション」とし、そのトランザクションが完全に行われたか否かによって、データを管理する方法である。そのため、処理の回復や削除の判断もトランザクション単位で行われる。例えば、クラッシュ時にトランザクションが不完全であれば、そのトランザクションはなかったこととして削除される。トランザクションがディスクにコミットして完了していれば、問題なく回復される。

 トランザクションは、ファイルシステムへの操作に対して生成される。ファイルシステムへの操作とは、ファイルの作成、削除、追加など、ファイルに関する操作である。では、トランザクションはどのようなタイミングで作成され、管理されるのだろうか?

 例として、ext3ファイルシステム上でファイルあるいはディレクトリの削除を行う場合を考えてみよう。ファイルやディレクトリの削除を行うには、「rm file」または「rm -r /dir」コマンドを使う。これらのコマンドを実行すると、以下の流れで処理が行われる。

 ジャーナリング処理はこのように、ローカル関数から呼び出される。そしてトランザクションを生成し、トランザクションが続く限り記録・更新され、すべての処理が終了した時点でトランザクションを終了させて元の関数に戻す。

 手順の中で行われるジャーナリング処理が、実際の記録操作である。ファイルシステムへの操作は2、3、5で、それを挟む形でジャーナリング処理が行われているのが分かる。後述するように、トランザクションは実際の変更を記録するためのジャーナル情報を持っており、変更が生じるたびにトランザクションの「メタ・データ記録」(ジャーナル情報)を更新する。

 3、5の実際のファイルシステムの操作によって、ファイルシステムの「メタ・データ」が更新されると、その都度トランザクションのジャーナル情報が更新され、更新された情報は定期的にコミット(ディスクにフラッシュ)される。これによって、新しい情報がジャーナルファイルに記録される。

トランザクション処理の流れ

 ジャーナリング処理では「トランザクションの生成、更新とコミット」が行われる。この手順はトランザクションの処理という観点から整理すると次のようになる。

  1. トランザクションの生成(処理内容などの情報の設定)
  2. トランザクションの実行(ジャーナルバッファへの書き込み、タイマの設定)
  3. プロセスにトランザクションの完了を通知
  4. タイマの期限が来たらログに記録(ジャーナルバッファのディスクへのコミット)
  5. チェックポイントでコミットが完了していたらログから破棄

 1〜3はプロセスの中で行われるジャーナリング処理で、4と5は後述するカーネルスレッドによって行われる。

ジャーナリング処理の内容

 ジャーナリング処理は、次の段階を踏んで行われる。実際のトランザクション処理は、その中の(1)(3)の手順で行われる。

  • 第1段階(開始)
     ext3では、ユーザープロセス(a)は、タスク構造体(注)の中にジャーナリングに関するトランザクションを管理するオブジェクト(ハンドル(b))を保持している。ジャーナリング処理は、開始時にプロセスが保持するこのハンドルを取得する。

注:カーネルがプロセスを管理するために利用する、task_struct型のタスクディスクリプタ。タスクに関するさまざまな情報が格納されている。


 ハンドルを取得するのは、プロセスがジャーナル情報を管理できる手段(ハンドル)を持つことで、プロセスが自分の持っているトランザクションの実行順序を間違えずにアトミック操作するためである。このハンドル(b)には、現在そのプロセスが実行しているトランザクション数やバッファ数が格納されている。

  • 第2段階(確認)
     次に、ハンドルの「ジャーナリング」のステータス情報を確認する。例えば、ほかのトランザクションが現在実行中の場合は、そのトランザクション操作が終了するのを待つ、あるいは逆に待たせるといった操作を行う。このような操作を行うことで、信頼性のための手順を厳密に守れるようにしている。
  • 第3段階(トランザクションの生成)
     ハンドルからの情報を確認し、トランザクションを実行しても大丈夫だと分かったら、実際の処理を行うためのトランザクションオブジェクト(c)(注)を取得する(1)。メタ・データのブロックアドレスなど、実際に記録するためのジャーナル(d)をトランザクションに設定し、さらにハンドルにトランザクションを登録する。こうして、ジャーナリング機能のためのフレームワークが作成される。いったんこのフレームワークを作成すると、このフレームワークを利用してトランザクションの整合性やコミット、メタ・データの更新を、発生に応じて逐次ジャーナリング処理していく。

注:トランザクション(オブジェクト)は、トランザクションの管理を行うためのデータ構造で、現在変更したメタ・データブロックのジャーナル情報、その状態(実行中であるかなど)やシーケンシャルな番号、タイマなどを管理する。前後関係が明確な「トランザクションID」という連続的な番号で管理される。


  • 第4段階(トランザクションの実行)
     ハンドルは、登録されたトランザクションにおいて実際にジャーナルに書き込む領域が十分であるか否かを確認する。さらに、ジャーナルが突然アボートされたりトランザクション待ちになっているといった問題がなければ、ハンドルに登録されているトランザクションを実行する(2)。無事に完了したら(3)、そのプロセスに操作が完了したことを通知する。

(1)トランザクションオブジェクトの取得

  • スーパーブロックに登録されたジャーナルのための変更情報と、手順、コミット時間(インターバル)をセットアップ
  • セットアップが完了したら、コミットのタイマをアクティブにしてタイマを登録

(2)トランザクションの実行

  • すでに動作中のトランザクションがあれば、そのトランザクションが終了するのを待って、トランザクションを実行(
  • バッファを書き込むための十分なスペースがジャーナルにない場合は、スペースを解放するための次のチェックポイントを待つ

(3)トランザクションの完了

  • トランザクションが完了したら、プロセスのジャーナリングのためのハンドルは解放される

注:実際のトランザクション実行は、タイマのセットアップとメタ・データバッファへの書き込みが完了した時点で完了する。実際のバッファの書き込みは、次のkjournaldによって行われる。


       1|2 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。