Understanding MySQL Internalsを読む(12)

連載記事一覧は*こちら*にあります。

http://mirz.jpでまとめて読むこともできます(オススメ)。

ストレージエンジンインタフェースが終わりといいつつまだあった。handlerton構造体について。

handlerton構造体

ストレージエンジンを独自に実装してMySQLに組み込みたい場合、handlerクラスを継承したクラスを実装すればいいのですが、それだけでは不十分です。その新しいストレージエンジンをMySQL本体側に教えてあげる必要があります。handlerton構造体はそのためのものです。

通常、handler実装クラスのインスタンスは各テーブルごと、さらに各テーブルに対してアクセスしている各スレッド毎にインスタンス化されます。従って、ひとことで"InnoDB"といってもhandlerインスタンスという点ではmysqldプロセス内に複数インスタンス化されているのです。一方、このhandlertonはそれぞれのストレージエンジンにつき、mysqldプロセス内で1つのみが存在します。オブジェクト指向アーキテクチャで"singleton"というインスタンスが1つであることを規定しているデザインパタンが
ありますが、"handlerton"という名前はそこからもじっているのではないかと思います。

このhandlerton構造体ですが、sql/handler.hに定義されています。mysqldがmain関数から起動すると、init_server_components関数を経て、ha_init関数での初期処理で使用されます。

  for (types= sys_table_types; *types; types++)
  {
    if (!(*types)->init || !(*types)->init())
      ha_was_inited_ok(types);
    else
      (*types)->state= SHOW_OPTION_DISABLED;
  }

typesはhandlerton構造体へのポインタのポインタ、sys_table_typesはsql/handler.ccで定義されているhandlerton構造体の配列です。

handlerton *sys_table_types[]=
{
  &myisam_hton,
  &heap_hton,
  &innobase_hton,
  &berkeley_hton,
  &blackhole_hton,
  &example_hton,
  &archive_hton,
  &tina_hton,
  &ndbcluster_hton,
  &federated_hton,
  &myisammrg_hton,
  &binlog_hton,
  &isam_hton,
  NULL
};

このように各エンジン用のhandlertonを登録しておくことで、mysqldの起動時にhandlerton->init関数ポインタによる呼出が行われて、各エンジンの初期処理が行われることでmysqld内で利用可能となります。

handlerton構造体のメンバは以下です。

メンバの型と名前 説明
const int interface_version Handlertonインタフェースのバージョン番号。MYSQL_HANDLERTON_INTERFACE_VERSIONの値が設定される。
const char *name ストレージエンジンの名前。
SHOW_COMP_OPTION state SHOW STORAGE ENGINESコマンドが発行された際に適切に出力するために必要。通常はSHOW_OPTION_YESが設定される。
const char *comment SHOW STORAGE ENGINESコマンドのCommentカラムの値として返される値。
enum legacy_db_type db_type 対象のテーブルからストレージエンジンの型を判別するためにfrmファイルで使用される値。
bool (*init)() ストレージエンジンを初期化するための関数。
uint slot MySQLで内部的に使用する変数。初期値は0である必要がある。
uint savepoint_offset savepointの格納領域へのオフセット。savepoint構造体のサイズで初期化されている必要がある。
int (*close_connection)(THD *thd) コネクションが閉じられたときにストレージエンジン側で必要におうじて終了処理を行うための関数。
int (*savepoint_set)(THD *thd, void *sv) savepointを扱うための関数。
int (*savepoint_rollback)(THD *thd, void *sv) ROLLBACK TO SAVEPOINTコマンドのための関数。
int (*savepoint_release)(THD *thd, void *sv) RELEASE SAVEPOINTコマンドのための関数。
int (*commit)(THD *thd, bool all) COMMITコマンドのための関数。
int (*rollback)(THD *thd, bool all) ROLLBACKコマンドのための関数。
int (*prepare)(THD *thd, bool all) XA PREPAREコマンドのための関数。
int (*recover)(XID *xid_list, uint len) XA RECOVERコマンドのための関数。
int (*commit_by_xid)(XID *xid) XA COMMITコマンドのための関数。
int (*rollback_by_xid)(XID *xid) XA ROLLBACKコマンドのための関数。
void *(*create_cursor_read_view)() カーソルをオープンするための関数。
void (*set_cursor_read_view)(void *) カーソルからフェッチするための関数。
void (*close_cursor_read_view)(void *) カーソルをクローズするための関数。
handler *(*create)(TABLE_SHARE *table) テーブルを作成するための関数。
void (*drop_database)(char* path) データベースを削除するための関数。
int (*panic)(enum ha_panic_function flag) 緊急停止を行うための関数。
int (*start_consistent_snapshot)(THD *thd) START TRANSACTION WITH CONSITENT SNAPSHOTコマンドのための関数。
bool (*flush_logs)() FLUSH LOGSコマンドのための関数。
bool (*show_status)(THD *thd, stat_print_fn *print, enum ha_stat_type stat) SHOW ENGINE STATUSコマンドのための関数。
uint (*partition_flags)() 異なるファイルシステムをまたがるようなテーブル・パーティショニングを扱えるかどうかを示すフラグを返す関数。
uint (*alter_table_flags)(uint flags) ALTER TABLEコマンドによる様々な操作が可能かどうかを示すフラグを返す関数。
int (*alter_tablespace)(THD *thd, st_alter_tablespace *ts_info) ALTER TABLESPACEコマンドのための関数。
int (*fill_files_table)(THD *thd, struct st_table_list *tables, class Item *cond) SELECT * FROM information_schema.files の実行結果を返すための関数。
uint32 flags ストレージエンジンが許容可能な操作についてのビットマスク。
int (*binlog_func)(THD *thd, enum_binlog_func fn, void *arg) レプリケーションでのログ操作を行うための関数。
void (*binlog_log_query)(THD *thd, enum_binlog_command binlog_command, const char *query, uint query_length, const char *db, const char *table_name) レプリケーション用のログにクエリが書き込まれる度に呼び出される関数。
int (*release_temporary_latches)(THD *thd) クライアントへレコードを送信する際、デッドロックが発生するのを回避するために、InnoDBのために作られた特別なコールバック関数。