MySQL 5.6 で動くストレージエンジン・テンプレート

MySQL 5.6 で動く Skeleton Engine, Yet Another Skeleton Engine を Github で公開してます.
https://github.com/laysakura/mysql-YetAnotherSkeletonEngine

Skeleton Engine は MySQL のストレージエンジンを作成するためのテンプレートです.
オリジナルのものは
http://www.sourcefiles.org/Databases/Utilities/
の skeleton_engine-0.7.tar.gz でダウンロード可能でした(2013/02/10 現在)が,古いバージョンの MySQL を前提としており,MySQL 5.6 にオリジナルのままの Skeleton Engine を組込むことはできません.
オリジナルのものが MySQL 5.6 で使えない理由は最後の節に記載します.

そこで Yet Another Skeleton Engine と名付けまして,MySQL 5.6 で動くストレージエンジンのテンプレートを公開しました.
本エントリでは,まず Yet Another Skeleton Engine の使い方を記し,次にメモ程度にリポジトリ作成作業のログを記します.

追記: 2013/02/17

Yet Another Skeleton Engine を使用中にクラッシュするバグを修正しました.
MySQL 5.6 本体の Example Storage Engine と同じコンパイルオプションを付けることでクラッシュはなくなった模様です.
https://github.com/laysakura/mysql-YetAnotherSkeletonEngine/commit/8b4f3c8d83b47c4e63d9257c92ea71051501841f

クラッシュの再現コードを本エントリの最後に付しておきます.

Yet Another Skeleton Engine の入手から使用まで

入手

1
2
git clone git://github.com/laysakura/mysql-YetAnotherSkeletonEngine.git
cd mysql-YetAnotherSkeletonEngine

ビルド・インストール

1
2
3
./configure  --with-mysql=[ビルド済みMySQLのソースディレクトリ]  --libdir=[MySQLのインストールディレクトリ]/lib/plugin
make
sudo make install

使用

1
2
sudo /etc/init.d/mysqld restart
mysql -u root -p

ここからは MySQL のシェルでインストール&確認です.

1
2
3
4
5
6
7
8
9
10
mysql> INSTALL PLUGIN YA_SKELETON SONAME 'libskeleton_engine.so';
Query OK, 0 rows affected (0.00 sec)

mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| EXAMPLE | YES | Example storage engine | NO | NO | NO |
| YA_SKELETON | YES | Yet Another Skeleton Storage Engine | NO | NO | NO |
...

YA_SKELETON というのが今回インストールした Yet Another Skeleton Engine です.
中身は EXAMPLE ストレージエンジンと全く同じなので,
http://dev.mysql.com/doc/refman/5.6/en/example-storage-engine.html
のように動作確認してみて下さい.

リポジトリ作成作業のログ

ディレクトリ作成

1
2
mkdir mysql-YetAnotherSkeletonEngine
cd mysql-YetAnotherSkeletonEngine/

必要ファイルをコピー

次のようなディレクトリ構成とする.

  • ~/src/skeleton_engine-0.7/: オリジナルの Skeleton Engine.
  • /usr/share/libtool/config/: ltmain.sh があるところ.
  • ~/src/mysql-5.6.10/: MySQL のソースディレクトリ.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cp ~/src/skeleton_engine-0.7/AUTHORS .
cp ~/src/skeleton_engine-0.7/COPYING .
cp ~/src/skeleton_engine-0.7/ChangeLog .
cp ~/src/skeleton_engine-0.7/INSTALL .
cp ~/src/skeleton_engine-0.7/Makefile.am .
cp ~/src/skeleton_engine-0.7/NEWS .
cp ~/src/skeleton_engine-0.7/README .
cp ~/src/skeleton_engine-0.7/README.windows .
cp ~/src/skeleton_engine-0.7/configure.in .

mkdir config
cp ~/src/skeleton_engine-0.7/config/ac_mysql.m4 config/
cp ~/src/skeleton_engine-0.7/config/dtrace.m4 config/
cp /usr/share/libtool/config/ltmain.sh config/ # ltmain.sh は何故か automake で作られなかったので・・・

mkdir src
cp ~/src/skeleton_engine-0.7/src/Makefile.am src/
cp ~/src/skeleton_engine-0.7/src/skeleton_probes.d src/
cp ~/src/skeleton_engine-0.7/src/skeleton_probes.h src/
cp ~/src/skeleton_engine-0.7/src/skeleton_config.h.in src/

# MySQL から example storage engine をコピー
cp ~/src/mysql-5.6.10/storage/example/ha_example.cc src/ha_skeleton.cc
cp ~/src/mysql-5.6.10/storage/example/ha_example.h src/ha_skeleton.h

いくつかのファイルの編集

(2013/02/13 - libmysqlservices を静的リンクしていた部分を動的リンクに変更)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# config/ac_mysql.m4 を編集
diff config/ac_mysql.m4.old config/ac_mysql.m4
10,12c10
< if test -d "$withval/sql"; then
< MYSQL_SRC="$i/mysql_config"
< fi
---
> MYSQL_SRC="$withval"

# configure.in を編集
diff configure.in.old configure.in
5c5
< AM_INIT_AUTOMAKE("skeleton_engine", 0.7)
---
> AM_INIT_AUTOMAKE("ya_skeleton_engine", 0.1)
20a21
> AC_SUBST(MYSQL_SRC)

# src/Makefile.am を編集
diff src/Makefile.am.old src/Makefile.am
16c16
< libskeleton_engine_la_LIBADD =
---
> libskeleton_engine_la_LIBADD = -lmysqlservices
22c22
< libskeleton_engine_la_LDFLAGS = -module
---
> libskeleton_engine_la_LDFLAGS = -module -L$(MYSQL_SRC)/libservices/

# ha_skeleton.cc を編集
diff src/ha_skeleton.cc.old src/ha_skeleton.cc
92c92
< #include "ha_example.h"
---
> #include "ha_skeleton.h"
980,982c980,982
< "EXAMPLE",
< "Brian Aker, MySQL AB",
< "Example storage engine",
---
> "YA_SKELETON",
> "Sho Nakatani",
> "Yet Another Skeleton Storage Engine",

configure を作る

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# aclocal
aclocal

# .h.in から .h を作る
autoheader

# automake で config/* や Makefile.in を作る
automake --add-missing --copy
configure.in:11: installing `config/config.guess'
configure.in:11: installing `config/config.sub'
configure.in:5: installing `config/install-sh'
configure.in:5: installing `config/missing'
src/Makefile.am: installing `config/depcomp'

# autoconf で configure を作る
autoconf

オリジナルの Skeleton Engine が MySQL 5.6 で使えない理由

ha_skeleton.* は古いバージョンの MySQL に対応して書かれており,インクルードしている一部ヘッダが MySQL 5.6 とは対応していません.

また,MySQL 5.6 のストレージエンジン開発では,libmysqlservices.so というライブラリのリンクが必要です.これを忘れると,いざ作成したライブラリを使おうとすると次のようにエラーになります.

1
2
mysql> INSTALL PLUGIN YOUR_NEW_ENGINE SONAME 'libskeleton_engine.so';
ERROR 1126 (HY000): Can't open shared library '/usr/local/mysql/lib/plugin/libskeleton_engine.so' (errno: 2 /usr/local/mysql/lib/plugin/libskeleton_engine.so: undefined symbol: my_snprintf_service)

参考: http://dev.mysql.com/doc/refman/5.6/en/compiling-plugin-libraries.html

おまけ: 2013/02/17 クラッシュバグ再現テスト

https://github.com/laysakura/mysql-YetAnotherSkeletonEngine/commit/8b4f3c8d83b47c4e63d9257c92ea71051501841f
の修正前に発生していたクラッシュバグを再現する Perl のテストコードを載せておきます.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/perl

use strict;
use warnings;

use DBI;

my $TEST_ROWS;
BEGIN {
$TEST_ROWS = $ENV{TEST_ROWS} || 1024;
};

use Test::More tests => $TEST_ROWS * 4 + 2;

use File::Basename;
use Cwd 'realpath';
my $testdir = realpath(dirname(__FILE__));

my $dbh = DBI->connect(
$ENV{DBI} || 'dbi:mysql:database=test;host=localhost',
$ENV{DBI_USER} || 'root',
$ENV{DBI_PASSWORD} || '',
) or die 'connection failed:';


## Crash bug repro
ok($dbh->do("drop table if exists t_example"));
ok($dbh->do("create table t_example (a INT) engine = ya_skeleton"));

for (my $i = 0; $i < $TEST_ROWS; $i++) {
ok($dbh->do("insert into t_example values (777),(333),(888)"));
}
for (my $i = 0; $i < $TEST_ROWS; $i++) {
ok($dbh->do("select * from t_example"));
}
for (my $i = 0; $i < $TEST_ROWS; $i++) {
ok($dbh->do("insert into t_example values (777),(333),(888)"));
ok($dbh->do("select * from t_example"));
}
author Sho Nakatani a.k.a. laysakura

東京大学大学院 情報理工学系研究科 電子情報学専攻 修士課程で並列分散処理・ストリーム処理・データベースを研究。
2014年4月に株式会社ディー・エヌ・エーにエンジニアスペシャリストとして入社し、ソーシャルゲームのサーバサイド共通基盤の開発に従事。
2016年8月より、オンライン証券会社株式会社FOLIOに入社。バックエンドシステム開発・プロジェクトマネージメント・Engineering Managementに従事。
2020年3月よりIdein株式会社所属。デバイス・高性能計算関連の研究開発。
2021年9月よりトヨタ自動車株式会社所属。自動車データの収集〜分析基盤の研究開発に従事。
その他個人事業主として、RDBMS開発やIntel SGXを利用するためのライブラリ開発などの活動。