バージョン5.1以降、MySQLは動的に接続されたプラグインのサポートを実装しています。 そして、ディストリビューションには-exampleというサンプルコードスケルトンが含まれています。 これは、ベースハンドラーである
ハンドラーのインターフェースと構造を記述します。
ハンドラーのコピーは、データベース接続ごとに個別に作成されます。 また、他のハンドラーとの同期に使用されるテーブル記述子
TABLE * tableと補助ベクトル
TABLE_SHARE * shareへのポインターも
受け取ります。 プラグイン開発はモジュール方式で実行でき、そもそも必要な機能のみを実装し、より複雑な操作をスタブで閉じます。
サンプルテンプレートはインターフェイスのみを記述し、操作を実行しないため、この例では、単一リンクリストに基づくCRUD操作の実装を追加します。
これを行うには、4つの関数のみを記述します。
- int rnd_init(ブールスキャン);
- int rnd_next(uchar * buf);
- int write_row(uchar * buf);
- int delete_row(const uchar * buf);
環境の準備サンプルテンプレートは、MySQLソースコードの
storage / exampleディレクトリの2つのファイル
ha_example.hおよび
ha_example.ccにあります。 この例では、
MySQL Community 5.5.35が使用されます。 まず、
例をコピーして、名前を
smalldbに変更し
ます 。
wget http://downloads.mysql.com/archives/get/file/mysql-5.5.35.tar.gz tar -zxvf mysql-5.5.35.tar.gz cd mysql-5.5.35 cp -rf storage/example storage/smalldb cd storage/smalldb sed -e 's/EXAMPLE/SMALLDB/g' -e 's/example/smalldb/g' ha_example.h > ha_smalldb.h sed -e 's/EXAMPLE/SMALLDB/g' -e 's/example/smalldb/g' ha_example.cc > ha_smalldb.cc sed -i 's/EXAMPLE/SMALLDB/g;s/example/smalldb/g' CMakeLists.txt
まず、単一リンクリストのプリセットと、先頭、現在、前、および次のリスト項目(
ha_smalldb.h内 )へのいくつかのポインターを追加することから始めましょう。
class node{ public: uchar* data;
次に、書き込み操作
-write_row(uchar * buf)に進みましょう。 引数として
bufが渡され、追加された文字列の内容が内部表現で含まれます。

予備処理を行わずにデータをメモリに保存するため、文字列の内容全体を単純にコピーできます。 メタデータを含む行の長さは、テーブル記述子
table-> s-> reclengthから取得できます。
int ha_smalldb::write_row(uchar *buf) { DBUG_ENTER("ha_smalldb::write_row"); node* n=new node(); n->data = (uchar*) malloc(sizeof(uchar)*table->s->reclength); memcpy(n->data,buf,table->s->reclength); append_node(n); row_count++; DBUG_RETURN(0); }
テーブルからデータを読み取るとき、一連の
rnd_initと
rnd_nextを使用した順次スキャン
が使用されます。 エンジンがインデックスまたは主キーをサポートしていない場合に使用されます。 まず、
rnd_init()でポインターを準備する必要があります。
int ha_smalldb::rnd_init(bool scan) { DBUG_ENTER("ha_smalldb::rnd_init"); cur=NULL; prev=NULL; next=first; cur_pos=0; DBUG_RETURN(0); }
ブール引数
スキャンは、テーブルをランダムに(一貫性なく)読み取るデータベースの意図を示します。 無視しても問題ありません。 未実現の
rnd_pos()コマンドを呼び出そうとすると、データベースは応答としてHA_ERR_WRONG_COMMANDを受け取り、順番に読む必要があると推測します。
単一の
rnd_init()の後、データベースはテーブルの最後
(HA_ERR_END_OF_FILE)に達するまで
rnd_next()を順番に呼び出します。 各呼び出しの後、
bufのメモリは、内部表現の文字列の内容で満たされる必要があります。
int ha_smalldb::rnd_next(uchar *buf) { int rc; DBUG_ENTER("ha_smalldb::rnd_next"); MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, TRUE); if (next!=NULL){ prev=cur; cur=next; next=cur->next; memcpy(buf,cur->data,table->s->reclength); cur_pos++; rc=0; }else{ rc= HA_ERR_END_OF_FILE; } MYSQL_READ_ROW_DONE(rc); DBUG_RETURN(rc); }
最後に、リストから現在のアイテムを削除して
delete_row()を記述します。
int ha_smalldb::delete_row(const uchar *buf) { DBUG_ENTER("ha_smalldb::delete_row"); if (cur!=first){ free(cur); prev->next=next; }else{ free(cur); cur=NULL; first=next; } row_count--; DBUG_RETURN(0); }
以上で、ミニエンジンの動作を体験できます。
設置MySQL 5.5では、コードのビルドにcmakeが使用されます。 インストールするには、.soファイルをコンパイルし、インストールされたバージョンのMySQLのpluginsディレクトリにコピーするだけです。 次のコマンドを使用して認識できます-SHOW VARIABLES LIKE "%plugin_dir%";
MySQL自体がインストールされていないか、
別のバージョンがインストールされている場合
は 、make installを使用してデータベースを追加インストールする必要があります。

INSERTおよびSELECTに加えて、
LIKE 、
INNER JOINなどの演算子を使用してさらに複雑なSQLクエリを実行できます。これは、SQLクエリの最適化がエンジンに制御を移す前にデータベースカーネルレベルで実装されるためですが、その有効性はもちろんエンジンでサポートされる機能に依存します
この資料が、MySQLプラグインのインターフェースに少し精通していることを願っています。 完全なプロジェクトコードは
githubからダウンロードできます。
MySQLエンジンの内部をより真剣に研究したいが、InnoDBに近づくリスクを冒したくない場合は、CSVまたはHEAP(新しい名前-MEMORY)に注意することをお勧めします。 CSVは、同じ形式でデータをディスクに保存する機能を追加します。 HEAPは、その名前が示すように、データをヒープに編成し、ハッシュインデックスのサポートを実装します。 どちらの場合も、行を削除した後にメモリの空きセクションを解放するという補助的な問題を解決する必要があります。これは、単一リンクリストを使用して回避できました。
独自のエンジンの作成に関する詳細なガイドは、
MySQL Internals Manualの 22章にあり
ます。 第22章カスタムストレージエンジンの作成 。
PSそして最後に、
ctagsユーティリティに慣れていない人には
ctagsユーティリティをお勧めします。 さまざまなファイルに散らばっているコードを調べるのに非常に便利です。たとえば、CTRL +]で関数または変数の定義にジャンプできます。 vim、emacs、およびその他の一般的なエディターのサポートがあります。 ここに
クイックガイドがあります。