MySQL RethinkDB 0.1 試してみました

少し前に話題になった、MySQLRethinkDBストレージエンジンを試してみました。

RethinkDBは、SSD向けに最適化されているところが特長です。

インストール時の注意事項

RethinkDBはMySQL 5.1のプラグイン形式を採用しているので、インストール自体はinstall pluginコマンドを打つだけです。ただし、プラグインglibcのバージョン2.7以上を要求しているため、使用できるディストリビューションがかなり限られています。
例えば、Red Hat Enterprise Linux 5(CentOS 5)のglibcは2.5なので動かすことができません。またRethinkDBはオープンソースソフトウェアではないので、自分でビルドしなおすことはできません。
今回は、glibc 2.10を採用しているFedora 11上で作業を行いました。RethinkDBはバージョン0.1を使用し、MySQLはRethinkDBが要求する5.1.31を事前にインストールしておきました。

mysql> install plugin RethinkDB soname 'ha_edb.so';
Query OK, 0 rows affected (0.01 sec)

mysql> show plugins;
 +------------+----------+----------------+-----------+---------+
 | Name       | Status   | Type           | Library   | License |
 +------------+----------+----------------+-----------+---------+
 | binlog     | ACTIVE   | STORAGE ENGINE | NULL      | GPL     |
 | partition  | ACTIVE   | STORAGE ENGINE | NULL      | GPL     |
 | ARCHIVE    | ACTIVE   | STORAGE ENGINE | NULL      | GPL     |
 | BLACKHOLE  | ACTIVE   | STORAGE ENGINE | NULL      | GPL     |
 | CSV        | ACTIVE   | STORAGE ENGINE | NULL      | GPL     |
 | FEDERATED  | DISABLED | STORAGE ENGINE | NULL      | GPL     |
 | MEMORY     | ACTIVE   | STORAGE ENGINE | NULL      | GPL     |
 | InnoDB     | ACTIVE   | STORAGE ENGINE | NULL      | GPL     |
 | MyISAM     | ACTIVE   | STORAGE ENGINE | NULL      | GPL     |
 | MRG_MYISAM | ACTIVE   | STORAGE ENGINE | NULL      | GPL     |
 | RethinkDB  | ACTIVE   | STORAGE ENGINE | ha_edb.so | GPL     |
 +------------+----------+----------------+-----------+---------+
11 rows in set (0.01 sec)

このように表示されればインストール成功です。今のところ、my.cnfに設定するパラメータは無いようです。

基本的な動作の確認

簡単に、動作を確認していきましょう。

# ls -l /var/lib/mysql
合計 272412
-rw-rw---- 1 mysql mysql       975 2009-09-16 10:17 fedora11-slow.log
-rw-rw---- 1 mysql root       4746 2009-09-16 10:17 fedora11.err
-rw-rw---- 1 mysql mysql         5 2009-09-16 10:17 fedora11.pid
-rw-rw---- 1 mysql mysql 134217728 2009-09-16 10:17 ib_logfile0
-rw-rw---- 1 mysql mysql 134217728 2009-09-16 10:01 ib_logfile1
-rw-rw---- 1 mysql mysql  10485760 2009-09-16 10:17 ibdata1
drwx--x--x 2 mysql mysql      4096 2009-09-16 09:53 mysql
srwxrwxrwx 1 mysql mysql         0 2009-09-16 10:17 mysql.sock
drwx------ 2 mysql mysql      4096 2009-09-16 13:10 scott

OS上のファイル構成を確認したところ、datadir直下にはRethinkDB関連のファイルはありませんでした。InnoDBがテーブルスペースファイルとログファイルを配置しているのとは対照的です。

# ls -l /var/lib/mysql/scott
合計 52
 -rw-rw---- 1 mysql mysql   61 2009-09-16 10:16 db.opt
 -rw-rw---- 1 mysql mysql 8624 2009-09-16 10:17 dept.frm
 -rw-rw---- 1 mysql mysql  176 2009-09-16 10:19 dept.rdbd
 -rw-rw---- 1 mysql mysql   16 2009-09-16 10:17 dept.rdbf
 -rw-rw---- 1 mysql mysql  555 2009-09-16 10:19 dept_PRIMARY.rdbi
 -rw-rw---- 1 mysql mysql 8780 2009-09-16 13:08 emp.frm
 -rw-rw---- 1 mysql mysql   20 2009-09-16 13:10 emp.rdbd
 -rw-rw---- 1 mysql mysql   27 2009-09-16 13:08 emp.rdbf
 -rw-rw---- 1 mysql mysql   68 2009-09-16 13:11 emp_PRIMARY.rdbi

データベース内には、テーブルごとにrdbd、rdbf、rdbiという3種類のファイルが作られます。rdbdにはテーブル、rdbiにはインデックスのデータが格納されているようです。ちなみにウェブでrdbd、rdbiという単語で検索してもそれらしいページがヒットしませんので、もしかしたらRethinkDBのレビュー記事は本稿が世界初かも知れません。

mysql> show create table dept\G
 *************************** 1. row ***************************
       Table: dept
Create Table: CREATE TABLE `dept` (
  `deptno` decimal(2,0) NOT NULL,
  `dname` varchar(14) DEFAULT NULL,
  `loc` varchar(13) DEFAULT NULL,
  PRIMARY KEY (`deptno`)
) ENGINE=RethinkDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

SHOW CREATE TABLEを見ると、ENGINE=RethinkDBとなっていることが確認できます。

mysql> create index dept_dname on dept (dname);
ERROR 1235 (42000): This version of MySQL doesn't yet support 'ALTER TABLE'

CREATE INDEXはまだ実装されていません。

mysql> CREATE TABLE `dept2` (
    ->   `deptno` decimal(2,0) NOT NULL,
    ->   `dname` varchar(14) DEFAULT NULL,
    ->   `loc` varchar(13) DEFAULT NULL,
    ->   PRIMARY KEY (`deptno`),
    ->   KEY (`dname`)
    -> ) ENGINE=RethinkDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.01 sec)

ただし、このようにCREATE TABLE時にあらかじめ追加のインデックスを付与しておくことは可能です。

# ls -l dept2*
 -rw-rw---- 1 mysql mysql 8624 2009-09-16 13:24 dept2.frm
 -rw-rw---- 1 mysql mysql  176 2009-09-16 13:25 dept2.rdbd
 -rw-rw---- 1 mysql mysql   26 2009-09-16 13:24 dept2.rdbf
 -rw-rw---- 1 mysql mysql  555 2009-09-16 13:25 dept2_PRIMARY.rdbi
 -rw-rw---- 1 mysql mysql 1039 2009-09-16 13:25 dept2_dname.rdbi

rdbiファイルは、インデックス1個あたり1ファイルが作成されるようです。

mysql> create table bonus
    ->        (ename varchar(10),
    ->         job varchar(9),
    ->         sal decimal,
    ->         comm decimal);
ERROR 1173 (42000): This table type requires a primary key

主キーなしのテーブルは作成できません。

mysql> analyze table dept\G
*************************** 1. row ***************************
   Table: scott.dept
      Op: analyze
Msg_type: note
Msg_text: The storage engine for the table doesn't support analyze
1 row in set (0.01 sec)

mysql> optimize table dept\G
*************************** 1. row ***************************
   Table: scott.dept
      Op: optimize
Msg_type: note
Msg_text: The storage engine for the table doesn't support optimize
1 row in set (0.00 sec)

管理系のコマンドはまだ実装されていません。

挙動が…

環境構築がうまくいったら負荷テストでもしてみようと思っていたのですが、どうも挙動がおかしいです。

mysql> insert into emp (empno, ename, deptno) values (9001, 'rethink', 40);
Query OK, 1 row affected (0.01 sec)

mysql> select empno, ename, deptno from emp where empno = 9001;
 +-------+---------+--------+
 | empno | ename   | deptno |
 +-------+---------+--------+
 |  9001 | rethink |     40 |
 +-------+---------+--------+
1 row in set (0.01 sec)

mysql> select empno, ename, deptno from emp where ename = 'rethink';
 +-------+---------+--------+
 | empno | ename   | deptno |
 +-------+---------+--------+
 |  9001 | rethink |     30 |
 +-------+---------+--------+
1 row in set (0.01 sec)

データが化けます。

mysql> insert into emp (empno, ename, deptno) values (9001, 'rethink', 40);
Query OK, 1 row affected (0.00 sec)

mysql> insert into emp (empno, ename, deptno) values (9001, 'rethink', 40);
Query OK, 1 row affected (0.00 sec)

あれ、主キー無視?

mysql> select * from emp where empno = 9001;
+-------+---------+------+------+----------+------+------+--------+
| empno | ename   | job  | mgr  | hiredate | sal  | comm | deptno |
+-------+---------+------+------+----------+------+------+--------+
|  9001 | rethink | NULL | NULL | NULL     | NULL | NULL |     40 |
+-------+---------+------+------+----------+------+------+--------+
1 row in set (0.00 sec)

1レコードしか入ってないのかな…

mysql> select * from emp where ename = 'rethink';
+-------+---------+------+------+----------+------+------+--------+
| empno | ename   | job  | mgr  | hiredate | sal  | comm | deptno |
+-------+---------+------+------+----------+------+------+--------+
|  9001 | rethink | NULL | NULL | NULL     | NULL | NULL |     30 |
|  9001 | rethink | NULL | NULL | NULL     | NULL | NULL |     30 |
+-------+---------+------+------+----------+------+------+--------+
2 rows in set (0.00 sec)

やっぱり2レコード入ってる!

mysql> delete from emp where empno = 9001;
Query OK, 1 row affected (0.00 sec)

どのレコードが消えたんだろう…

mysql> delete from emp where empno = 9001;
ERROR 2013 (HY000): Lost connection to MySQL server during query

サーバが落ちた><

えーと

というわけで、まともに動きません。
SSD向けに最適化されたストレージエンジンの調査をするつもりが、ネタ記事になってしまいました。RethinkDB 0.1はまだPre-Alpha版とのことなので、仕方ないかな…しばらく待ちたいと思います。