Understanding MySQL Internalsを読む(5)

以前の記事

NET構造体

NET構造体はMySQLのclient/serverプロトコルで良く使われる構造体らしいです。あまりMySQLプロトコル関係のコードを弄ったことがないので自分的にはあまり馴染みがありません。でもどうやら、プロトコル関係の関数ではNET構造体はほぼ常に第一引数に指定されていて重要みたいです。

というわけでNET構造体についてもメンバを解説していきます(訳だけど)。NET構造体はinclude/mysql_com.hに定義されています。

メンバの型と名前 説明
Vio* vio 低レベルなネットワークI/Oソケットの記述子。VioのVはVirtualの略。VIOによるネットワークの抽象化レイヤは最初はSSL対応のために実装され、その後はWindowsの共有メモリと名前付パイプによる接続に対応するためにも利用されている。またこうした仮想化・抽象化がネットワーク関連のコードの移植性を高めるのに一役買っている。
unsigned char* buff データバッファの先端。
unsigned char* buff_end データバッファの終端。
unsigned char* write_pos データバッファの中の次に書き込みを行う位置へのポインタ。
unsigned char* read_pos データバッファの中の次に読み込みを行う位置へのポインタ。
my_socket fd Perl DBI/DBDクライアントインタフェースをサポートするために必要な変数。OSのソケット記述子の番号が格納されている。
unsigned long max_packet 現在のネットワークパケットバッファのサイズ。システム変数のnet_buffer_lengthの値で初期化されているが、必要に応じてシステム変数のmax_allowed_packetの値まで自動的拡張される。
unsigned long max_packet_size パケットサイズの最大値。システム変数のmax_allowed_packetで設定可能。
unsigned int pkt_nr 現在のパケットのシーケンス番号(圧縮プロトコルを使わない時向け)。シーケンス番号はプロトコル上の整合性チェックのために使用される。ハードウェアやOSに問題が無い限り、シーケンス番号がおかしい場合はバグが原因である。
unsigned int compress_pkt_nr 圧縮プロトコルを使用している場合の現在のパケットのシーケンス番号
unsigned int write_timeout ネットワーク書き込み処理のタイムアウト判定用設定値。システム変数net_write_timeoutで設定可能。
unsigned int read_timeout ネットワーク読み込み処理のタイムアウト判定用設定値。システム変数net_read_timeoutで設定可能。
unsigned int retry_count ネットワークI/O処理が失敗した際、最終的なエラーと判定するまでに何回リトライすべきかの設定値。多くのプラットフォームでは正常に送受信できるような状況でも種々の理由により中断されてしまうケースがあり、1度の失敗でエラーにするのは良くない。システム変数net_retry_countで設定可能。
int fcntl 現在はこの変数は使用されていない。削除される予定。
my_bool compress 圧縮プロトコルが使用される場合には1に設定される。
unsigned long remain_in_buf 圧縮プロトコルを使用している場合には、読み込み時に圧縮されたパケット長よりも多くの読み込みをしてしまう場合がある。この場合、その次のパケット分も同時に読んでしまっていることになり問題となる。この変数はこの超過分を追跡するためのもの。圧縮プロトコルが使用されていない場合には、パケットのヘッダを読んでそこに記されているパケット長に従って読み込みを行うので、そのような事態は発生しない。従って圧縮プロトコルが使用されていない場合にはこの変数も使われない。この圧縮プロトコルむけのアルゴリズムは例えばパケットサイズが小さいような場合、効率的な実装とは言えない。今後、この実装は変更される可能性がある。
unsigned long length パケットに含まれるデータのバイト長(ヘッダ以外の長さ)。
unsigned long buf_length パケット用バッファの長さ。パケットヘッダはこれに含まれない。また圧縮プロトコルを使用している場合には次のパケットのヘッダ・データも含んでいる可能性があることに注意。
unsigned long where_b read_pos - buffの値。現在読み込み中のバッファに対するオフセットの意味。
unsigned int *return_status この接続に関連したTHDオブジェクトのserver_status変数へのポインタ。
unsigned char reading_or_writing 読み書きの状態を表すフラグ。何もしていないときは0、読み込み中は1、書き込み中は2を設定する。SHOW PROCESSLISTコマンドから参照される。
char save_char ある種のクライアントルーチンはパケットデータの終端の後につづくデータが0x0であると推定できるとき、よりよいパフォーマンスを出すことができる。圧縮プロトコルが使われている場合(次のパケットがすぐ後に来ている場合があるので)、データ終端の後に0x0を上書きするのは危険である。この変数は上書き前に値と保存し、後で復元する際に参照するために使用される。
my_bool no_send_ok 通常、サーバ上で処理が成功した場合には、クライアントに対してはOKパケットによってその報告が行われる。しかしそのような望ましい状況ではない場合にはこの変数は1に設定され、OKパケットは送信されなくなる。
char last_error[MYSQL_ERRMSG_SIZE] クライアントに対して送られた最新のエラーメッセージ文字列を含むバッファ。もしエラーメッセージが含まれていない場合、最初のバイトは0x0に設定されている。
char sqlstate[SQLSTATE_LENGTH+1] ODBCドライバとJDBCドライバによって利用されるSQLStateの値を含むバッファ。
unsinged int last_errno クライアントに対して送られた最新のMySQLエラーコード。エラーが発生していない場合には0が設定されている。
unsigned char error I/O処理が成功した場合には0、何かプロトコル上の論理的なエラーが発生した場合には1、システムコールあるいは標準ライブラリ関数からエラーを受け取った場合には2、大きなパケットがサイズ拡張に失敗してスキップされた場合(特別な場合)には3が設定される。
gptr query_cache_query ネットワークI/Oコードとクエリキャッシュコードの間の同期を適切に行うために使用される。
my_bool report_error クライアントにエラーを報告すべき場合に1が設定される。
my_bool return_errno クライアントにMySQLエラーコードを報告すべき場合に1が設定される。

こんなところ。

TABLE構造体

Tritonn開発者的にはおなじみの構造体。

TABLE構造体はテーブル記述子を定義したもの。テーブルはopenかcloseのどちらかの状態に常にあり、テーブルを使うためにはopenされていないといけない。テーブルをopenすると、テーブル記述子が作成され、テーブルキャッシュに追加される。このテーブルキャッシュは後で同じテーブルにアクセスする際に再利用される。

TABLE構造体はパーサ、オプティマイザ、アクセス制御、クエリキャッシュなどの機能で頻繁に参照される(あともちろんテーブルに対する参照・更新時にも。ただしTABLE構造体は上位層限定。エンジンではまた別の構造体がエンジンごとに定義されているのだ)。sql/table.hにst_table構造体が定義され、sql/handler.hにてTABLEがtypedefされている。

TABLE構造体はver5.1でリファクタリングされ、一部のメンバはTABLE_SHAREクラスに移っていることに注意。TABLE構造体は各スレッドごとに作成されるが(テーブルキャッシュはスレッド単位ですよ!)、このTABLE_SHAREインスタンスはsingletonなやつで、物理的なテーブルごとに1つ作成される。

TABLE構造体は大きな構造体なので基本的なメンバのみとりあげることにする。

メンバの型と名前 説明
handler *file このテーブルを扱っているストレージエンジンオブジェクトへのポインタ。実体はha_myisamだったりha_innodbだったり。
Field **field テーブルに含まれるフィールドへのポインタの配列。フィールドの総数はfields変数に設定されている。
HASH name_hash フィールドを名前から特定するためのハッシュ。フィールド数がMAX_FIELDS_BEFORE_HASH(sql/mysql_priv.hにて定義,=32)よりも多い場合に使用される。
byte *record[2] オプティマイザによって使用される、レコード操作のための一時的なバッファの対。
uint fields テーブルに含まれるフィールドの数。
uint reclength レコードのバイト長。ここでいうバイト長はオプティマイザによってメモリ上で処理される際の長さ。ストレージエンジンではまた別の話。
uint rec_buff_length レコードを1行操作するために一時的に割り当てられたバッファの長さ。
uint keys テーブルに含まれるキーの数。
uint key_parts MySQL用語では複合キーに含まれるカラムは"key part"と呼ばれている。key partの数が格納されている変数。ここでは延べ数が使用さえる。
uint primary_key キー配列における、主キーのインデックス値。主キーが存在する場合(主キーは先頭に置かれるので)、この値は0が設定されている。主キーが存在しない場合にはMAX_KEY(sql/unireg.hにて定義、=64)が設定されている。
uint null_fields テーブルに含まれるフィールドのうち、NULL値を許可しているフィールドの数。
uint blob_fields テーブルに含まれるフィールドのうち、BLOB系およびTEXT系のデータ型を使用しているフィールドの数。
key_map key_in_use このテーブルに対するクエリを処理する際に利用可能なキーのマップ。ALTER TABLE .. DISABLE KEYSで無効化しているキーを除いた全てのキーが含まれている。
key_map quick_keys 現在のクエリにおける範囲検索用オプティマイザが利用可能なキーのマップ。範囲検索用のオプティマイザとは例えばlast_nameというフィールドにキーが作成されている場合、SELECT * FROM phonebook WHERE last_name > 'A' AND last_name = 'B' というクエリを処理するのにストレージエンジンが範囲に含まれるキーに基づいた読み込みを行える場合に使用される。
key_map used_keys 現在のクエリを処理するのに使用できるキーのマップ。key_in_useと似ているが、こちらはFORCE KEYやIGNORE KEYの指定によるフィルタリングを行った後のもの。
key_map keys_in_use_for_query FORCE KEYおよびIGNORE KEYによって指定されたキーのマップ。
KEY *key_info このテーブルに作成されたキーの配列。配列の長さは変数keysに格納されている。
TYPELIB keynames キーの名前から配列インデックスをlookupするためのテーブル。
ha_rows max_rows テーブル作成時に指定されたMAX_ROWSの値。これはいわゆるhard limitとして機能するものではないが、ストレージエンジンが最適なレコードフォーマットを選択するためのヒントとなる。
ha_rows min_rows テーブル作成時に指定されたMIN_ROWSの値。この値はfrmファイルに格納されている。
ulong avg_row_length テーブル作成時に指定されたAVG_ROW_LENGTHの値。これはストレージエンジンへのヒントとなる。
TYPELIB fieldnames フィールドの名前から配列インデックスをlookupするためのテーブル。
enum db_type db_type このテーブルを扱うストレージエンジンの型。
enum row_type row_type このテーブルのレコードの型(dynamic,fixedなど)
uint db_create_options テーブル作成時に指定されたオプションのビットマスク。
uint db_stat このテーブルに対してどんな操作が可能かを示すビットマスク。
uint status 最後に操作したレコードのステータスを示すビットマスク。
enum tmp_table_type tmp_table このテーブルが一時テーブルではない場合にはNO_TMP_TABLE、トランザクションに対応していない一時テーブルである場合にはTMP_TABLE、トランザクション対応の一時テーブルである場合にはTRANSACTIONAL_TMP_TABLEが設定される。
my_bool force_index FORCE INDEXによってこのテーブルのキーが指定されている場合には1が設定される。
my_bool key_read このテーブルに対するデータ検索でインデックスを使用する場合にオプティマイザによって設定されるフラグ。
my_bool db_low_byte_first 整数型のフィールドがエンジンによってどのようなバイトオーダーで書き込まれるかについての変数。下位バイトから書き込まれる(little endian)場合には1が設定される。
my_bool fulltext_searched fulltextインデックスを使用する場合にオプティマイザによって設定されるフラグ。
my_bool crashed ストレージエンジンによってテーブルが破損していると報告された場合に1が設定される。
my_bool no_keyread いくつかの特別な事情によりキーが使用されるべきではない場合にオプティマイザにそれを伝えるためのフラグ。
Field *next_number_field フィールドがauto_incrementを使用している場合に使用する記述子へのポインタの配列。auto_incrementを使用しないフィールドについては0x0が設定されている。
Field_timestamp *timestamp_field フィールドがtimestampを使用している場合に使用する記述子へのポインタの配列。timestampを使用しないフィールドについては0x0が設定されている。
CHARSET_INFO *table_charset このテーブルのデフォルトの文字コード
MEM_ROOT mem_root テーブル記述子のさまざまなメンバで使用されるメモリプール。
GRANT_INFO grant このテーブルについてのアクセス制御用の記述子。
char *table_cache_key テーブルキャッシュの中からこのテーブル記述子を特定するためのハッシュキー。データベース名,'\0',テーブル名,'\0',および一時テーブルのためのオプショナルな文字列を連結させたもの。table_cache_keyはデータベース名を参照するために頻繁に使用される。
char *table_name テーブル名。エイリアスが指定されている場合にはエイリアス名。
char *real_name テーブル名。
char *path このテーブルの.frmファイルのパス。データディレクトリからの相対パスで、拡張子".frm"を取り除いたもの。例えば"./test/t1"など。
uint key_length table_cache_keyのバイト長。
table_map map JOIN処理を行う際に各テーブルインスタンスには番号が割り当てられる。この変数はテーブルの番号の一式に対応する1bitのビットマスク。
ulong version メモリ上にあるテーブルキャッシュが最新のものかどうかを確認するために使用される。他のスレッドがFLUSH TABLESを実行した場合、テーブル記述子の妥当性は失われる。これはグローバル変数のrefresh_versionと一致しているかどうかで確認される。
FILESORT_INFO sort レコードポインタをソートするための構造体。GROUP BYやORDER BYを処理するために利用される。
ORDER *group 一時テーブルの中でGROUP BYを処理するためにオプティマイザによって使用される。このテクニックが使われる場合、一時テーブル内にキーが生成される。
ha_rows quick_rows[MAX_KEY] 範囲検索用のオプティマイザが推定した検索結果件数が格納される。
ulong query_id このテーブル記述子を使用しているクエリのID。
uchar frm_version frmファイルのフォーマットのバージョン。
THD *in_use このテーブル記述子を使用している接続のTHDオブジェクトへのポインタ。
struct st_table *next Linked Listの次のテーブル。
struct st_table *prev Linked Listの前のテーブル。

ふー。