MySQLのコアモジュールについて

*半年間、MySQLを基礎からやり直すことにしたので、その間に勉強したことをQiitaに投稿していきます。*

# MySQLのコアモジュール一覧
- サーバ初期化モジュール
- 接続マネージャ
- スレッドマネージャ
- 接続スレッド
- ユーザ認証モジュール
- アクセス制御モジュール
- パーサ
- コマンドディスパッチャ
- クエリキャッシュモジュール
- オプティマイザ
- テーブルマネージャ
- テーブル変更モジュール
- テーブルメンテナンスモジュール
- ステータスレポーティングモジュール
- 抽象ストレージエンジンインタフェース(テーブルハンドラ)
- ストレージエンジン実装(MyISAM、InnoDB、MEMORY、Berkeley DB)
- ロギングモジュール
- レプリケーションマスタモジュール
- レプリケーションスレーブモジュール
- クライアント/サーバプロトコル API
- 低レベルネットワーク I/O API
- コア API

# MySQLコアモジュールのフローチャート図
![mysql_module_flowchart.png](https://qiita-image-store.s3.amazonaws.com/0/43504/a048fe3f-d7b7-0800-3c78-fdcf6c6edf7a.png)

# コアモジュール毎の詳解

## サーバ初期化モジュール
サーバ起動時の初期化するのに使われるモジュール
コードのほとんどは、sql/mysqld.ccに書かれており、エントリポイントはmain()になり、以下の関数などが記述されている

- init_common_variables()
- init_thread_environment()
- init_server_components()
- sql/sql_acl.cc の grant_init()
- sql/slave.cc の init_slave()
- get_options()

## 接続マネージャ
接続マネージャは、クライアントからの着信接続をリッスンし、要求をスレッドマネージャへ送るのに使われるモジュール
実際は、sql/mysqld.ccの関数、handle_connections_sockets()が、モジュールそのものになる

## スレッドマネージャ
スレッドマネージャはスレッドの追跡や、クライアントからの接続を処理する為にスレッドを割り当てるのに使われるモジュール
コードのほとんどは、sql/mysqld.ccに書かれており、エントリポイントは create_new_thread()になる

## 接続スレッド
接続スレッドは、確立された接続上でクライアント要求を処理するのに使われるモジュール
また、その作業の核になっている
接続スレッドは、sql/sql_parse.ccのhandle_one_connection()という1つの関数から形成されている

## ユーザ認証モジュール
ユーザ認証モジュールは、接続ユーザを認証し、ユーザの権限レベルに関する情報を含んだ構造体であり、変数を初期化するのに使われるモジュール
ユーザ認証モジュールのエントリポイントはsql/sql_parse.ccの check_connection()になる
sql/sql_acl.ccとsql/password.ccのコードにも以下の関数などが記述されている

- sql/sql_acl.ccのacl_check_host()
- sql/password.ccのcreate_random_string()
- sql/sql_parse.ccのcheck_user()
- sql/sql_acl.ccのacl_getroot()

## アクセス制御モジュール
アクセス制御モジュールは、要求した操作を実行するのにクライアントユーザが十分な権限を持っているかを検証するのに使われるモジュール
コードのほとんどは sql/sql_acl.cc に書かれているが、最も頻繁に使用される関数の1つである check_access()は sql/sql_parse.cc に書かれており、他にも以下の関数などがある

- sql/sql_acl.ccのcheck_grant()
- sql/sql_parse.ccのcheck_table_access()
- sql/sql_acl.ccのcheck_grant_column()
- sql/sql_acl.ccのacl_get()

## パーサ
パーサは、クエリの解析と解析ツリーの生成をするのに使われているモジュール
エントリポイントはsql/sql_parse.ccのmysql_parse()であり、この関数はいくつかの初期化を実行し、それからyyparse()を呼び出している
また他にも、以下の関数などがある

- sql/gen_lex_hash.cc
- sql/lex.h
- sql/lex_symbol.h
- sql/lex_hash.h(生成されるファイル)
- sql/sql_lex.h
- sql/sql_lex.cc
- ファイル名が item_で始まり、拡張子に.hまたは.ccを持つsql/下のファイルのグループ

## コマンドディスパッチャ
コマンドディスパッチャは、要求の解決方法を知っている下位レベルのモジュールに要求を転送するのに使われているモジュール
コマンドディスパッチャは、sql/sql_parse.ccのdo_command()と dispatch_command()の2つの関数で形成されている

## クエリキャッシュモジュール
クエリキャッシュモジュールはクエリ結果をキャッシュし、可能な場合にキャッシュされた結果を配信し、クエリ実行のショートカットをするのに使われているモジュール
クエリキャッシュモジュールは、sql/sql_cache.ccに書かれており、以下の関数などが記述されている

- Query_cache::store_query()
- Query_cache::send_result_to_client()


## オプティマイザ
オプティマイザは、クエリに答えるために最もよい戦略を作成し、また結果をクライアントに提供するためにその戦略を実行するのに使われているモジュール
MySQLコードの中で最も複雑なモジュール
エントリポイントはsql/sql_select.ccでmysql_select()になる
sql/sql_select.ccのコードに、以下の関数などが記述されている

- JOIN::prepare()
- JOIN::optimize()
- JOIN::exec()
- make_join_statistics()
- find_best_combination()
- optimize_cond()

また、複雑なコアのオプティマイザとは違いsql/opt_range.ccという別ファイルに収められ、個別に扱われている範囲オプティマイザとうものがある
範囲オプティマイザは、指定の値の範囲または範囲セットを持つキーを使用するクエリを最適化するのに使われている
その範囲オプティマイザのエントリポイントは、SQL_SELECT::test_quick_select()になる

## テーブルマネージャ
テーブルマネージャは、テーブル定義ファイル(拡張子.frm)の作成、読み取り、変更と、テーブルキャッシュと呼ばれるテーブルディスクリプタのキャッシュの管理、およびテーブルレベルロックの管理をするのに使われているモジュール
コードのほとんどはsql/sql_base.cc、sql/table.cc、sql/unireg.cc、sql/lock.ccに書かれている
それらのファイルには、以下の関数などが記述されている

- sql/table.ccのopenfrm()
- sql/unireg.ccのopenfrm()
- sql/sql_base.ccのopen_table()
- sql/sql_base.ccのopen_tables()
- sql/sql_base.ccのopen_ltable()
- sql/lock.ccのmysql_lock_table()  

## テーブル変更モジュール
テーブル変更モジュールは、テーブルの作成や削除、テーブル名の変更、およびレコード
の削除、更新、挿入をするのに使われているモジュール
それぞれの変更は、以下のエントリポイントから開始される

- sql/sql_table.ccのmysql_create_table()
- sql/sql_table.ccのmysql_alter_table()
- sql/sql_table.ccのmysql_rm_table()
- sql/sql_delete.ccのmysql_delete()

## テーブルメンテナンスモジュール
テーブルメンテナンスモジュールは、チェック、修復、バックアップ、リストア、最適化(デフラグメント)、分析(更新キーの配布統計)などのテーブルメンテナンス処理をするのに使われるモジュール
テーブルメンテナンスモジュールのこーどのほとんどは、sql/sql_table.ccに書かれている
また、コア関数は以下の便利なラッパーを持つmysql_admin_table()になる

- mysql_check_table()
- mysql_repair_table()
- mysql_backup_table()
- mysql_restore_table()
- mysql_optimize_table()
- mysql_analyze_table()

mysql_admin_table()は要求を適切なストレージエンジンメソッドに送り、作業の大半はストレージエンジンレベルで起きている

## ステータスレポーティングモジュール
ステータスレポーティングモジュールは、サーバ設定、パフォーマンス追跡変数、テーブル構造情報、レプリケーションの進捗、テーブルキャッシュの状態などのクエリに答えるのに使われるモジュール
ステータスレポーティングモジュールは、SHOWで始まるクエリを処理する
コードのほとんどは、sql/sql_show.ccに書かれており、以下の関数などが記述されている

- mysqld_list_processes()
- mysqld_show()
- mysqld_show_create()
- mysqld_show_fields()
- mysqld_show_open_tables()
- mysqld_show_warnings()
- sql/slave.ccのshow_master_info()
- sql/sql_repl.ccのshow_binlog_info()

## 抽象ストレージエンジンインタフェース(テーブルハンドラ)
テーブルハンドラは、低レベルのストレージとデータ取得処理を実行するための標準化インタフェースを提供するのに使われるモジュール
テーブルハンドラは、実際にはhandlerと呼ばれる抽象クラスであり、かつhandlertonと呼ばれる構造体である
テーブルハンドラは、sql/handler.hで定義され、sql/handler.ccで一部実装されている
派生の特定のストレージエンジンクラスは、このクラスの純粋仮想メソッドを実装するひつようがある

## ストレージエンジン実装(MyISAM、InnoDB、MEMORY、Berkeley DB)
それぞれのストレージエンジンは、テーブルハンドラ(handlerクラス)を拡張することにより、各種オペレーションのための標準インタフェースを提供するのに使われるモジュール
派生クラスのメソッドは、特定のストレージエンジンの低レベルの呼び出しについての標準インタフェース処理を定義している
主に、下記のファイル、ディレクトリ配下にコードが有る

- sql/ha_myisam.hとsql/ha_myisam.cc
- sql/ha_innodb.hとsql/ha_innodb.cc
- sql/ha_heap.hとsql/ha_heap.cc
- sql/ha_ndbcluster.hとsql/ha_ndbcluster.cc
- myisam/
- innobase/
- heap/
- ndb/

## ロギングモジュール
ロギングモジュールは、上位レベルの(論理)ログの管理するのに使われるモジュール
ストレージエンジンが追加機能的に、自身の目的の為に自身の下位レベルの(物理または論理)ログを管理することもあり得るが、ロギングモジュールはそれらの処理には関与していない。
現時点での論理ログには、以下のものがある

- バイナリ更新ログ(主にレプリケーションで使用)
- コマンドログ(主にサーバ監視とアプリケーションデバッグで使用)
- スロークエリログ(最適化が貧弱なクエリ追跡のために使用)がある

ロギングのほとんどの処理はバイナリレプリケーションログで起こり、ログイベント作成用のクラスおよびバイナリレプリケーションログの読み取り用のクラスは、sql/log_event.hで定義され、sql/log_event.ccで実装されている。
レプリケーションマスタとレプリケーションスレーブのどちらのモジュールも、ロギングモジュールのこの機能に大きく依存している

## レプリケーションマスタモジュール
レプリケーションマスタモジュールは、マスタのレプリケーション機能に使われるモジュール
レプリケーションマスタモジュールの最も一般的な処理は、レプリケーションログイベントの継続的なフィードを要求に応じてスレーブに提供することである
コードのほとんどは、sql/sql_repl.ccにあり、コア関数はmysql_binlog_send()になる

## レプリケーションスレーブモジュール
レプリケーションスレーブモジュールは、スレーブのレプリケーション機能に使われるモジュール
スレーブの役割はマスタから更新を取得し、その更新をスレーブに適用することである
バージョン4.0から導入されたスレーブには、以下の2つのスレッドが用意されている

- ネットワークI/Oスレッド
 - マスタに継続的に更新のフィードを要求し、受け取った更新の内容をローカルのリレーログに記録する
- SQL スレッド
 - リレーログから更新を読み出し てその更新をスレッドに適用する

レプリケーションスレーブモジュールは、sql/slave.ccのコードに書かれており、以下の関数などが記述されている

- handle_slave_io()
- handle_slave_sql()

## クライアント/サーバプロトコル API
クライアント/サーバプロトコルAPIは、プロトコルパケットの作成、読み出し、解釈、送信のためにサーバ間で用いられるAPIを実装するのに使われるモジュール
MySQLクライアント/サーバ通信プロトコルは、プロトコルスタックにおいてオペレーティングシ
ステムプロトコル(TCP/IPまたはローカルソケット)の上に位置している。
クライアント/サーバプロトコル APIは、sql/protocol.cc、sql/protocol.h、sql/net_serv.ccに書かれている
sql/protocol.hとsql/protocol.ccは、クラスの階層を定義し、実装しており、Protocolが基底クラスで、Protocol_simple、Protocol_prep、Protocol_cursorは、そのクラスから派生するクラスになっている
また、それぞれのファイルには以下の関数などが記述されている

- sql/net_serv.ccのmy_net_read()
- sql/net_serv.ccのmy_net_write()
- sql/protocol.ccのnet_store_data()
- sql/protocol.ccのsend_ok()
- sql/protocol.ccのsend_error()

## 低レベルネットワーク I/O API
低レベルネットワークI/O APIは、低レベルのネットワークI/OおよびSSLセッションに対する
抽象化を提供するのに使われるモジュール
低レベルネットワーク I/O APIのコードは vio/ディレクトリに書かれており、すべての関数の名前は vio_で始まっている

## コア API
コア APIは、移植可能ファイル I/O、メモリ管理、文字列操作、ファイルシステムナビゲーション、出力のフォーマット、データ構造およびアルゴリズムのリッチなコレクションなど数多くの機能を提供するのに使われるモジュール
コア APIはMySQLの万能ナイフの役割を担っているモジュールであり、MySQLの奇跡を形成するコアコンポーネントとも言える
何らかの問題が生じた場合、大半はコア APIモジュールの中にその解決策があり、ない場合はそのコード化が行われることになる
コア APIのコードは、mysys/とstrings/の各ディレクトリにあり、コア API関数の名前の多くはmy_で始まっている

参考：[詳解MySQL](http://www.oreilly.co.jp/books/9784873113432/)