MySQL道普請便り

第84回 ストレージエンジンをビルドしてみる

この記事を読むのに必要な時間:およそ 5 分

MySQLのストレージエンジンはプラガブルになっていて,ユーザが作成したストレージエンジンを使うことができます。と聞いたら皆さん何がしたくなるでしょうか。作ってみたくなりますよね。⁠自作ストレージエンジン」… なんとも素晴らしく良い響きだと思いませんか?

というわけで,ストレージエンジンを自作する方法について説明していきたいと思います。今回はその第一歩として,EXAMPLEストレージエンジンをビルドして試してみましょう。

環境設定

今回は,MySQL8.0.13をapt-getを使ってインストールして進めております。OSはUbuntu18.04を利用して進めます。

MySQL8.0をインストールするために,公式からAPTのレポジトリを公式のページからダウンロードしてきてインストールします。

$ curl -o mysql.deb https://repo.mysql.com/mysql-apt-config_0.8.10-1_all.deb
$ sudo dpkg -i mysql.deb

dpkgを実行すると下のような画面が表示されますので,MySQL Server & Cluster (Currently selected: mysql-8.0)が mysql-8.0になっていることを確認して<Ok>ではなくてOKを選びましょう。

dpkg画面

dpkg画面

その後,sudo apt-get install -yをしてからsudo apt-get install -y mysqlでインストールするとversion8系のMySQLがインストールされます。初期パスワードの設定も途中で行います。

現在インストールされているストレージエンジンを確認する

インストールが終わった時点で,どのようなストレージエンジンが入っているのかをSHOW ENGINES構文を使って検証してみましょう。

mysql> SHOW ENGINES;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)

このように表示されると思います。Engineの中には,見知ったInnoDBMyISAMといったストレージエンジンが並んでいると思います。今回は,ここにEXAMPLEエンジンを自力でコンパイルして追加することを目指します。9件であったことを覚えておいてください。

Exampleストレージエンジン

Exampleストレージエンジンは,その名の通りストレージエンジンを作る際の手引きとなるストレージエンジンです。このストレージエンジンをベースにいろいろと作成してみると良いでしょう。ちなみに,このストレージエンジンを使ってテーブルを作成することができますが,データを挿入することはできません。

MySQLのビルドを行ってみる

ストレージエンジンをビルドするのに一番簡単な方法としては,時間がかかるとは思いますが,MySQL全体をビルドしてしまうのが,たぶん一番簡単だと思います。

ソースコードをバージョンと合わせてダウンロードを行います。今回は,MySQL8.0.13のソースコードを公式からダウンロードしてきて適当なディレクトリに展開して進めていきます。

$ cd /tmp
$  wget  https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-boost-8.0.13.tar.gz
$ tar xzvf mysql-boost-8.0.13.tar.gz

さて,ビルドするにあたっていくつかソフトウェアを追加します。cmakencurseslibsslをインストールする必要があります。今回ビルドに使用したOSはubuntuなのでapt-getを使ってインストールします。

$ sudo apt-get install -y cmake libncurses5-dev libssl-dev build-essential

さてここからがビルドの本番です。解凍されてできたディレクトリに移動しcmake .を実行してみると,以下のようなエラーが発生します。

$ cd mysql-8.0.13
$ cmake .
-- Running cmake version 3.10.2
-- MySQL 8.0.13

〈中略〉

CMake Error at cmake/boost.cmake:101 (MESSAGE):
  You can download it with -DDOWNLOAD_BOOST=1 -DWITH_BOOST=<directory>

  This CMake script will look for boost in <directory>.  If it is not there,
  it will download and unpack it (in that directory) for you.

  If you are inside a firewall, you may need to use an https proxy:

  export https_proxy=http://example.com:80

Call Stack (most recent call first):
  cmake/boost.cmake:289 (COULD_NOT_FIND_BOOST)
  CMakeLists.txt:739 (INCLUDE)

〈略〉

上記のエラーで,C++ライブラリのBOOSTが足りないと怒られるのですが,今回はBOOSTも一緒にダウンロードしているので-DWITH_BOOST=./boostとすることで実行できます。またその他にもBOOSTライブラリをダウンロードする方法として,-DDOWNLOAD_BOOST=1 -DWITH_BOOST=/tmp/BOOSTオプションを付ける方法があります。もう一度実行します。

$  cmake . -DWITH_BOOST=./boost
-- Running cmake version 3.10.2
-- MySQL 8.0.13

$ make

こうするとビルドが始まりますのでしばらく待ちましょう。MySQLのビルドにはメモリーがかなり必要なため,エラーになってしまった場合はメモリを足すか,スワップファイルを作成して,コンパイルが終わるのを待ちましょう。

ちなみに,EXAMPLEストレージエンジンだけをコンパイルしたい場合やスペック的に厳しい場合などは,makeを行うところにexampleオプションを追加してmake exampleとすることでEXAMPLEストレージエンジンだけをコンパイルすることもできます。

ビルドしたストレージエンジンをインストールする

今回はtmpディレクトリでビルドしたので,正常にビルドが終わっていれば/tmp/mysql-8.0.13/plugin_output_directoryの中にha_example.soファイルができていると思います。

このファイルをINSTALL PLUGIN構文を使ってインストールをするだけなのですが,横着をして絶対パスでそのまま実行してみます。

mysql> INSTALL PLUGIN example SONAME '/tmp/mysql-8.0.13/plugin_output_directory/ha_example.so';
ERROR 1124 (HY000): No paths allowed for shared library

するとこのようにエラーが発生します。これは,読み込みが認められていないディレクトリから読み込もうとしたためエラーになりました。では続けて,どこからなら読み込みができるのかをSHOW VARIABLE構文を使って確認してみましょう。

mysql> show variables like '%plugin_dir%';
+---------------+------------------------+
| Variable_name | Value                  |
+---------------+------------------------+
| plugin_dir    | /usr/lib/mysql/plugin/ |
+---------------+------------------------+
1 row in set (0.00 sec)

以上のような結果になりました。この結果から/usr/lib/mysql/plugin/の下に配置すれば良さそうだとわかります。ディレクトリを移動して実行してみましょう。

$ sudo mv /tmp/mysql-8.0.13/plugin_output_directory/ha_example.so /usr/lib/mysql/plugin
$ ls
adt_null.so                         component_log_sink_syseventlog.so  ha_example.so     libpluginmecab.so   semisync_master.so
auth_socket.so                      component_validate_password.so     innodb_engine.so  locking_service.so  semisync_slave.so
authentication_ldap_sasl_client.so  connection_control.so              keyring_file.so   mypluglib.so        validate_password.so
component_log_filter_dragnet.so     debug                              keyring_udf.so    mysql_no_login.so   version_token.so
component_log_sink_json.so          group_replication.so               libmemcached.so   rewriter.so

配置が終わりましたので,MySQLからもう一度インストールを実行してみます。

mysql> INSTALL PLUGIN example SONAME 'ha_example.so';
Query OK, 0 rows affected (0.05 sec)

今度はエラーになりませんでした。SHOW ENGINESで本当にインストールができているかを確認してみましょう。

mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| EXAMPLE            | YES     | Example storage engine                                         | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
10 rows in set (0.00 sec)

一番最初にEXAMPLEストレージエンジンが追加されたことがわかると思います。件数も,最初に表示されていたときと比較して10件に増えていることがわかると思います。また,実際にテーブルを作成することもできます。

mysql> create table example_test(id int) ENGINE=example;
Query OK, 0 rows affected (0.04 sec)

インストールしたストレージエンジンをアンインストールしたい場合は,UNINSTALL PLUGIN構文でアンインストールできます。

mysql> UNINSTALL PLUGIN example;
Query OK, 0 rows affected (0.09 sec)

ただし,使ってるテーブルが存在した状態でアンインストールをしてしまうと,アンインストールしたときではなくクエリの実行時にエラーになるので注意をしましょう。

mysql> select * from example_test;
ERROR 1286 (42000): Unknown storage engine 'EXAMPLE'

まとめ

今回はEXAMPLEストレージエンジンを使って,実際にストレージエンジンをビルドして動かして見るところまで試してみました。ビルドの初回は非常に時間がかかってしまいますが,2回目以降はキャッシュされたファイルが使えるので高速にコンパイルできるようになると思います。みなさんも,ぜひ一度ストレージエンジンを自分でコンパイルして動かしてみてはいかがでしょうか。

著者プロフィール

木村浩一郎(きむらこういちろう)

GMOメディア株式会社 技術推進室所属のWebアプリケーションエンジニア。最近はミドルウェア・インフラ周りのことも少しずつ学習しています。趣味は将棋。好きな戦法は四間飛車。

Twitter:@kk2170

コメント

コメントの記入