ちょっと硬派なコンピュータフリークのBlogです。

カスタム検索

2009-10-26

MySQL Clusterソースコード探検隊!

これまで「MySQL Clusterの進化とその構造について」および「NDBカーネルブロックの種類」について説明した。今日はその続きとしてMySQL Clusterのソースコードについて紹介しようと思う。シグナルを交換し合うマルチプルステートマシンは間違いなくこれからの時代にフィットするアーキテクチャなので、MySQL Clusterに興味を持たれた方が「膨大なMySQL Clusterのソースコードを探検する場合にどの入り口から入ればいいのか」ということを判断する一助になればと思う。とりとめなく書いてるのであんまりまとまってないかも知れないが、その点は容赦して頂きたい。

まず、ソースコードの入手方法であるが、これは最新のソースツリーをBazaarで入手する方法と、MySQLのWebページからダウンロードする方法の2つがある。Bazaarで入手するには、次のコマンドを実行すれば良い。(Bazaarを事前にインストールしておこう。)

shell> bzr branch lp:~mysql/mysql-server/mysql-cluster-7.0

するとカレントディレクトリ以下にソースコードがコピーされる。結構時間がかかるので注意しよう。

MySQLのWebページからダウンロードするには、次のページをブラウザでアクセスしよう。

http://dev.mysql.com/downloads/cluster.html

するとプラットフォームの選択メニューが出てくるので、ZIP形式のソースコードが欲しければWindowsを、TAR形式のものが欲しければLinuxを選択しよう。一番小さいファイルがソースコードである。ソースコードのファイルはmysql-cluster-gpl-VERSION.tar.gzというような名前になっている。

MySQL Clusterのソースコードが含まれる場所は次の2つである。

  • src-top-dir/storage/ndb
  • src-top-dir/sql

src-top-dirはソースコードのトップディレクトリ、つまりZIPまたはTARファイルを展開したときに作成されるディレクトリ(mysql-cluster-gpl-VERSIONというような名前のディレクトリ)のことである。

storage/ndbにはndbdやndb_mgmdといったコマンドのソースコードが収められている。つまりSQLノードを除く全てのコマンドのソースコードはここにある。一方、sqlディレクトリにはSQLノードのソースコードが格納されている。ファイル名はha_ndbcluster*。(*はワイルドカード。)ここは元々mysqldのソースコードが収められているディレクトリなので、そこに居候しているのである。(将来的にはstorage/ndbへ移動したいらしいが、タスクの優先順位は低くなかなかそうならない。)肝心のNDBカーネルのソースコードはstorage/ndb以下にあるのでこちらを中心に説明する。ha_ndbcluster*には、ストレージエンジンとしてMySQL Clusterへアクセスする際に必要なソースコード、つまりmysqldがNDB APIを通じてNDBにアクセスするためのロジックが記述されているので、ストレージエンジンAPIおよびNDB API興味のある人は覗いて見るといいだろう。

ここからは、NDBカーネルのソースコードを見る際のポイントについて列挙しよう。

  • NDBカーネルのソースコードの位置は、storage/ndb/src/kernelである。main()関数を含むmain.cppはこのディレクトリである。ndbdの初期化プロセスについて知りたい場合には、main.cppを見よう。
  • ヘッダファイル類はstorage/ndb/include/kernel配下に収められている。C++のヘッダファイルはstorage/ndb/src/kernel以下にも含まれているが、共通のヘッダファイルはこちらのディレクトリに含まれているので注意しよう。
  • storage/ndb/src/kernel/vmには、PLEX仮想実行環境のソースコードが含まれている。最も重要なのはSimulatedBlock.[c|h]ppで、ここで定義されているSimulatedBLockクラスはこれらは全てのブロックの親クラスとなる。つまり、NDBDカーネル内の各ブロックは、SimulatedBlockクラスを継承しているのである。また、SimulatedBlockが交換するメッセージは、VMSignal.[c|h]ppで定義されている。(シグナルを表すクラスはSignalである。)面白いことに、SimulatedBlockは他のあらゆるカーネルブロックへ、sendSignal()関数を通じてシグナルを送信することが出来る。同じプロセス内のブロックであろうが、他のホストで動作しているブロックであろうが、同じ方法(関数)でシグナルを送信することが出来るのである。
  • storage/ndb/src/kernel/blocksには各ブロックのソースコードが含まれている。ブロックごとにサブディレクトリに分かれているので見易いだろう。ここで定義されている各カーネルブロックは、上記の通りSimulatedBlockクラスを継承している。各カーネルブロックの動作を定義しているこのディレクトリは、NDBのソースコードの心臓部と言っていいだろう。
  • storage/ndb/include/kernel/BlockNumbers.hには、各カーネルブロックのIDが定義されている。ブロック番号は16ビット符号無し整数なのだが、同じく16ビット符号無し整数であるノードIDと組み合わせることで、32ビットの符号無し整数としてクラスタ全体を通じたID(BlockReference)を合成することが出来る。storage/ndb/include/kernel/RefConvert.hppにはノードIDとブロック番号からBlockReferenceへ変換するロジックおよびその逆が定義されている。(ただのビット演算だけどね!)
  • storage/ndb/src/kernel/SimBlockList.cppには、作成したカーネルブロックのインスタンス化と、そのインスタンスへのポインタをリストにして保管しておくためのロジックが記述されている。ただし、NDBカーネルの各ブロックはインスタンス化された段階ではまだ初期化されず、その後STTORシグナルを受け取った時点で初期化が始まる点には注意したい。
  • storage/ndb/include/kernel/GlobalSignalNumbers.hでは、各シグナルにつけられた番号が記述されている。実に700種類以上のシグナルが定義されている!(2009年10月現在)
  • storage/ndb/include/kernel/signaldataディレクトリには、シグナルにおいて送信されるデータ(ペイロード)を定義するクラスのソースコードが格納されている。シグナルが送信するデータはフリーフォーマット(単なるワード列)なので、頻繁に利用されるデータについてはその構造が定義されているのである。
  • storage/ndb/src/common/transporterディレクトリには、トランスポーターに関するソースコードが格納されている。トランスポーターとは、MySQL Clusterの各ノード同士が通信し合うための仮想的なインターフェイスである。これにより、通信する実際のプロトコル(TCP/IPなのかSCIなのか)に因らないロジックの記述が可能になる。
  • storage/ndb/src/mgmsrvディレクトリには、管理ノードのソースコードが格納されている。特に重要なのはstorage/ndb/src/mgmsrv/ConfigInfo.cppで、このファイルには各種設定パラメーターとそのデフォルト値に関する記述がなされている。また、storage/ndb/src/mgmclientにはndb_mgmコマンドのソースコードが、storage/ndb/src/mgmapiにはNDB MGM API(設定情報をやり取りするためのAPI)のソースコードが格納されている。
  • storage/ndb/src/ndbapiディレクトリには、NDB APIに関するソースコードが格納されている。
そんなわけでMySQL Clusterのソースコードのレイアウトについてとりとめもなく紹介してみた。「よし、ソースコードを見るか!」と思った時に参考にして頂けると幸いである。

0 コメント:

コメントを投稿