TEXIおよびtexi2htmlの表示
TEXIはGNU標準ドキュメント形式です。さまざまなユーティリティを使い、TEXIのソースドキュメントを他の(おそらくもっと読みやすくて移植性のある)形式に変換することができます。Emacsやそれに類するエディタでは、TEXI形式を読みやすくするTEXIメジャーモードがサポートされています。
HTML形式で表示したければ、texi2htmlという無料のPerlベースのユーティリティを利用できます。このユーティリティでは、TEXIのソースドキュメントから、非常に柔軟な設定ができるHTML出力を生成できます。texi2htmlはhttp://cvs.savannah.gnu.org/viewvc/texi2html/texi2html/からダウンロードできます。このユーティリティをダウンロードしたら、次のような方法でインストールします。
# tar -xzvf texi2html-1.76.tar.gz # cd texi2html-1.6 # ./configure # make install
ここでは、執筆時点の最新版のtexi2htmlを展開し、Linuxシステムにインストールしています。次に、ソース配布物に含まれる「internals.texi」ドキュメントのHTML版を生成します。
# cd /path/to/mysql-5.0.2-alpha/ # texi2html Docs/internals.texi
このコマンドを実行すると、ソースツリーの/Docsディレクトリに「internals.html」という新しいHTMLドキュメントが生成されます。これで、内部構造のドキュメントをWebブラウザで参照できるようになります。参考のために、このHTMLドキュメントもhttp://www.jpipes.com/で公開しています。
MySQLのアーキテクチャの概要
MySQLのアーキテクチャは、相互に関連する関数セットの集まりで構成されます。これらが連携し、データベースサーバのさまざまな要求を満たします。多くの著者が、これらの関数セットは実際にはコンポーネント、つまり完全にカプセル化されたパッケージであることを示唆しています(※3)。しかし、ソースコードにはこれが事実であることを示す証拠はほとんどありません。
たしかに、このアーキテクチャには類似のタスクを処理する関数から成る独立した関数ライブラリが含まれています。しかし、従来のオブジェクト指向プログラミングの意味での、完全なコンポーネントレベルの機能の分離は行われていません。ですから、ソースコードでBufferManagerやQueryManagerというクラスを探しても期待を裏切られることになります。そのようなクラスは存在しないからです。一部の開発者、特にJavaの経験を持つ開発者にとっては、クライアントオブジェクトの要求をオブジェクト中心のアプローチで満たすために各種の「マネージャ」オブジェクトを含むコードを書くのが普通のことになっていますが、MySQLでは状況が異なります。
場合によっては、特にクエリキャッシュやログ管理サブシステムのソースコードでは、オブジェクト指向に近いアプローチを取っていることがあります。しかしほとんどの場合、MySQLのシステム機能は、各種の関数ライブラリ(構造体のコアセットの引渡しを担当)とクラス(コード実行の詳細を担当)を通じて実行されます。カプセル化されたアプローチのような、コンポーネント自身が内部の実行を管理し、他のコンポーネントに対してAPIを提供するという形は取りません。
その理由の1つとして、システムアーキテクチャが複数の言語で書かれており、CとC++の両方のソースファイル、およびユーティリティとして機能する多数のPerlおよびシェルスクリプトで構成されていることが挙げられます。CとC++では機能上の特性が異なります。C++は完全なオブジェクト指向言語で、Cは手続き型に近い言語です。MySQLのシステムアーキテクチャでは、特定のライブラリがすべてCで書かれているため、オブジェクト指向のコンポーネント型のアーキテクチャを実現することはほぼ不可能です。もちろん、サーバーサブシステムのアーキテクチャはパフォーマンスと移植性の問題にも大きくかかわっています。
さらに、ソースコードや内部構造のドキュメントを分析すると、コンポーネントやパッケージについて言及されている部分がほとんどないことがわかります(※4)。代わりに、さまざまなタスク関連の機能についての記述が見つかります。たとえば、内部構造のTEXIドキュメントでは「オプティマイザ」に言及していますが、ソースコードにはOptimizerという名前のコンポーネントもパッケージもありません。代わりに、内部構造のTEXIドキュメントには、「オプティマイザは、RDBMSでクエリ用にどの実行パスを選択すべきかを判断する一連のルーチンである」と記載されています。わかりやすくするために、ここでは関連する一連の各機能を「コンポーネント」ではなく「サブシステム」と呼ぶことにします。そのほうが、さまざまな関数ライブラリの構成をより正確に表しているように思われるからです。
init_server_components()関数は奇妙な例外です。ただし実際には、このメソッドはいくつかの機能サブシステムの起動時に実行され、ストレージハンドラとコアバッファを初期化します。各サブシステムは、サーバの他のサブシステムからの情報を受け付けるとともに、他のサブシステムにデータを提供するように設計されています。これを標準的な方法で行うために、これらのサブシステムは明確に定義された「関数アプリケーションプログラミングインターフェイス(API)」を通じてこの機能を公開します(※5)。サーバのパイプラインを通じて要求とデータが送られると、サブシステムはこれらの明確に定義された関数とデータ構造を介して相互に情報をやりとりします。ここでは、それぞれの主要なサブシステムについて考察しながら、これらのデータ構造とメソッドの一部を見ていきます。
MySQLサーバのサブシステムの構成
MySQLサーバーアーキテクチャの全体の構成は、レイヤー型ではあるものの、特に階層型ではない構造をしています。ここでこのような区別をしているのは、MySQLサーバーアーキテクチャのサブシステムが互いにまったく依存していないからです。
階層型の構成では、コンポーネントがツリー状の一連のクラスから派生するため、サブシステムは互いに依存して機能します。たしかに、一部のサブシステム(特にSQL解析および最適化サブシステム)内にはツリー状のクラスの構成がありますが、サブシステム自体は階層型の配置に従っていません。
基本関数ライブラリおよびサブシステムの特定のグループは、低レベルの処理を担っています。これらのライブラリとサブシステムは、ストレージエンジンシステムの抽象化をサポートする役目を果たしています。ストレージエンジンシステムは、要求側のクライアントプログラムにデータを提供します。図1に、このレイヤー構造の全体図とそれらのサブシステムを示します。
クライアントプログラムがストレージエンジンの抽象化されたAPIとやりとりしている点に注意してください。これにより、クライアント接続はストレージエンジンに依存しないステートメントを発行することができます。つまり、クライアントはどのストレージエンジンがデータ要求を処理しているかを知る必要がありません。InnoDBとMyISAMのどちらのレコードを取得する場合でも、クライアントに特別な機能は必要ありません。このしくみのおかげで、MySQLではさまざまなストレージ要件とメディアに合わせて機能を拡張することができます。
基本関数ライブラリ
MySQLのすべてのサブシステムは、共通関数の基本ライブラリを共有して使います。これらの関数の多くは、サブシステム(および開発者)がオペレーティングシステム、メインメモリ、または物理的なハードウェア自体を直接操作せずに済むようにするために存在しています(※6)。さらに、基本関数ライブラリによって、コードの再利用と移植が可能になります。この基本ライブラリの大部分の関数は、/mysysおよび/stringsディレクトリのCソースファイルにあります。表2に、この基本ライブラリのコアファイルと場所の一部を示します。
| ファイル | 内容 |
| /mysys/array.c | 動的配列の関数と定義 |
| /mysys/hash.c/.h | ハッシュテーブルの関数と定義 |
| /mysys/mf_qsort.c | クイックソートのアルゴリズムと関数 |
| /mysys/string.c | 動的文字列の関数 |
| /mysys/my_alloc.c | いくつかのメモリ割り当てルーチン |
| /mysys/mf_pack.c | ファイル名およびディレクトリパスのパッキングルーチン |
| /strings/* | 低レベルの文字列およびメモリ操作の関数、およびいくつかのデータ型の定義 |
まとめ
データベースサーバの内部構造の世界への小旅行をお楽しみいただいたでしょうか。本稿では、MySQLのソースコードを手に入れる方法と、ドキュメントをさまざまな形式で設定および取得する方法を紹介しました。次に、サーバのサブシステムの全体的な構成の概要について説明しました。

