MySQL界隈を賑わせているMyRocks。
2017/5/23リリースの MariaDB 10.2.6 にMyRocks(RocksDB)エンジン(alpha)が追加されましたので、InnoDBのテーブルを変換して使ってみました。
はじめに
注意事項と結論ですが、本番用途ならMyRocksもチューニングしないとダメそうです。それは本記事の範囲外です。
チューニングについては、オフィシャルにもこのような記述があります。
Unfortunately, configuring RocksDB optimally is not trivial. Even we as RocksDB developers don't fully understand the effect of each configuration change. If you want to fully optimize RocksDB for your workload, we recommend experiments and benchmarking, while keeping an eye on the three amplification factors.
要約すると、「まだ熟れてないから自分で試してね」ということですね。
また、そもそも本記事執筆時点で RocksDBはAlphaリリース です。
MariaDBの準備
インストールと簡単な設定を記載しておきます。
インストール
最新のMariaDBを入れましょう。本記事執筆時点では10.2.7
が最新ですが、検証環境を構築した時点では10.2.6
が最新でした。
本記事の環境はCentOS7
をOSとして、以下のパッケージを入れている環境です。
- MariaDB-client-10.2.6-1.el7.centos.x86_64
- MariaDB-shared-10.2.6-1.el7.centos.x86_64
- MariaDB-common-10.2.6-1.el7.centos.x86_64
- MariaDB-devel-10.2.6-1.el7.centos.x86_64
- MariaDB-compat-10.2.6-1.el7.centos.x86_64
- MariaDB-server-10.2.6-1.el7.centos.x86_64
- MariaDB-rocksdb-engine-10.2.6-1.el7.centos.x86_64
10.2.6
の時点では MyRocksはMariaDB-rocksdb-engine
という別のプラグインパッケージになっています ので、MariaDB-server
と合わせて入れましょう。
簡単な設定
自動的にrocksdb.cnf
というファイルが作成されていると思います。
$ cat /etc/my.cnf.d/rocksdb.cnf
[mariadb]
plugin-load-add=ha_rocksdb.so
この記述さえあればRocksDBエンジンが有効化されます。
MariaDBを起動したときに以下のようにRocksDBエンジンが有効になっていることが確認できるはずです。
MariaDB> SHOW ENGINES;
+--------------------+---------+----------------------------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------------------------+--------------+------+------------+
| ROCKSDB | YES | RocksDB storage engine | YES | YES | YES | ←これ
| MRG_MyISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| Aria | YES | Crash-safe tables with MyISAM heritage | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| Mroonga | YES | CJK-ready fulltext search, column store | NO | NO | NO |
| SEQUENCE | YES | Generated tables filled with sequential values | YES | NO | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, foreign keys and encryption for tables | YES | YES | YES |
+--------------------+---------+----------------------------------------------------------------------------------+--------------+------+------------+
10 rows in set (0.00 sec)
ROCKSDB
が見えますよね。InnoDB同様の機能を有していることもわかります。
設定値補足
後継バージョンでは直っているかもしれませんので補足程度ですが・・・
MariaDB 10.2.6
ではRocksDBのディレクトリがデータベースのように認識されて「#mysql50#.rocksdb
」というデータベースが見えてしまいます。(既知の不具合です)
上記設定ファイルに以下のパラメータを追加しておけばその問題を回避できます。
ignore-db-dirs=.rocksdb
データベースの移行
MariaDBの準備も整ったので、データを移行してみます。
PerconaのXtraBackupが非常に高速で便利です。
環境情報
今回の検証では、以下の環境間/バージョン間でデータの移行に成功しています。
(XtraBackupについては、単に手間を惜しんだだけなので、最新バージョンを使う方が良いですね)
- 移行元: CentOS6 + MySQL 5.6.12 + XtraBackup 2.2.11
- 移行先: CentOS7 + MariaDB 10.2.6 + XtraBackup 2.3.6
バックアップ〜リストア
本題ではないのでさくっと書きます。
バックアップ
移行元のMySQLサーバーで以下のようにバックアップを取ります。
各種パスや、parallel
の値、lz4の圧縮率などは任意に変更してください。
[MySQLサーバー]
$ mkdir /var/tmp/tmp.xtrabackup
### 認証情報が必要な場合はオプションを付ける
$ innobackupex --stream=xbstream --parallel=4 --socket=/var/lib/mysql/mysql.sock /var/tmp/tmp.xtrabackup | lz4 -4 > /var/tmp/dbbackup.xbstream.lz4
こうして作成された/var/tmp/dbbackup.xbstream.lz4
を移行先に転送します。
リストア
移行先のMariaDBサーバーで以下のコマンドでリストアします。
当然ながら、今あるデータは全て吹き飛びますのでご注意下さい。
[MariaDBサーバー]
### 作業ディレクトリに移動
$ mkdir /var/tmp/tmp.xtrabackup
$ cd /var/tmp/tmp.xtrabackup
### 展開とリストア可能状態への変換
$ lz4 -d /var/tmp/dbbackup.xbstream.lz4 | xbstream -x -v
$ innobackupex --apply-log ./
### リストア
$ mv /var/lib/mysql /var/tmp/.
$ innobackupex --move-back ./
$ chown -R mysql:mysql /var/lib/mysql
あとはMariaDBを起動すれば、リストア完了です。
もしログに「please run mysql_upgrade」の文字列が出力されているときは、mysql_upgrade
を打っておくと良いでしょう。
$ mysql_upgrade
RocksDBへの変換
事前準備
Perconaの(pt-online-schema-change)https://www.percona.com/software/database-tools/percona-toolkitは優秀で、RocksDBに切り替えるときにも利用できます。
オフィシャルページの指示に従って入れておきましょう。
今回の検証バージョンは以下です。
- percona-toolkit-3.0.3-1.el7.x86_64
元のテーブルの情報
hoge
というテーブルを対象にします。
mysql> SHOW CREATE TABLE hoge\G
中略
ENGINE=InnoDB AUTO_INCREMENT=19103259 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED
これはほぼ本番相当のデータが入っている、圧縮済みInnoDBのテーブルです。
なお、下記の行数(tbl_rows)は概算なので参考程度に捉えてください。
mysql> select
-> table_name, engine, table_rows as tbl_rows, avg_row_length as rlen,
-> floor((data_length+index_length)/1024/1024) as allMB,
-> floor((data_length)/1024/1024) as dMB,
-> floor((index_length)/1024/1024) as iMB
-> from information_schema.tables
-> where table_schema=database() and table_name='hoge';
+------------+--------+----------+------+-------+------+------+
| table_name | engine | tbl_rows | rlen | allMB | dMB | iMB |
+------------+--------+----------+------+-------+------+------+
| hoge | InnoDB | 16005625 | 605 | 13065 | 9240 | 3825 |
+------------+--------+----------+------+-------+------+------+
1 row in set (0.03 sec)
エンジンの変換
このコマンドを打つイメージで、pt-oscを実行します。
ALTER TABLE hoge ENGINE=ROCKSDB ROW_FORMAT=Dynamic;
非常に時間がかかるので、nohup
で投げ込みましょう。
### Dryrun
$ nohup pt-online-schema-change --charset=utf8 --nocheck-replication-filters --alter "ENGINE=ROCKSDB ROW_FORMAT=Dynamic" h=localhost,D=DBNAME,t=hoge,u=root --socket=/var/lib/mysql/mysql.sock --dry-run 2>&1 > /tmp/pt-osc.log &
### Execute
$ nohup pt-online-schema-change --charset=utf8 --nocheck-replication-filters --alter "ENGINE=ROCKSDB ROW_FORMAT=Dynamic" h=localhost,D=DBNAME,t=hoge,u=root --socket=/var/lib/mysql/mysql.sock --execute 2>&1 > /tmp/pt-osc.log &
検証環境(OpenstackのVM)では6時間強掛かりました。
変換後の確認
もう一度information_schema
から情報を取ってみましょう。
MariaDB> select
-> table_name, engine, table_rows as tbl_rows, avg_row_length as rlen,
-> floor((data_length+index_length)/1024/1024) as allMB,
-> floor((data_length)/1024/1024) as dMB,
-> floor((index_length)/1024/1024) as iMB
-> from information_schema.tables
-> where table_schema=database() and table_name='hoge';
+------------+---------+----------+------+-------+------+------+
| table_name | engine | tbl_rows | rlen | allMB | dMB | iMB |
+------------+---------+----------+------+-------+------+------+
| hoge | ROCKSDB | 17774854 | 585 | 11937 | 9926 | 2010 |
+------------+---------+----------+------+-------+------+------+
1 row in set (0.00 sec)
RocksDBになっていることが確認できます。わずかに容量も減っていますね。
使ってみる
試しに全件COUNTのクエリを投げてみます。
- 注意1) Indexが使われるため実際のデータフルスキャンとは違いますが・・・参考に捉えていただければ。
- 注意2) 違う日に比較しているので結果(件数)が異なりますが、おおよそ同じデータ量なので差異は無視してください。
MySQL 5.6 + InnoDB
このhoge
テーブルはなかなか大きいので、暖気前だとDiskReadが激しいことになります。
mysql> SELECT SQL_NO_CACHE COUNT(*) FROM hoge;
+----------+
| COUNT(*) |
+----------+
| 17824275 |
+----------+
1 row in set (48.98 sec)
暖気後はバッファプールに乗るため、多少は速い結果となります。
(それでも4秒かかってますね・・・)
mysql> SELECT SQL_NO_CACHE COUNT(*) FROM hoge;
+----------+
| COUNT(*) |
+----------+
| 17824275 |
+----------+
1 row in set (4.03 sec)
MariaDB + RocksDB
MySQLと同様に投げ込んでみます。
MariaDB> SELECT SQL_NO_CACHE COUNT(*) FROM hoge;
+----------+
| COUNT(*) |
+----------+
| 17774854 |
+----------+
1 row in set (48.76 sec)
ほぼ同じ時間となりました。ディスク上のデータサイズがほぼ一緒だったので、納得はできます。
暖気後はどうでしょう。
MariaDB> SELECT SQL_NO_CACHE COUNT(*) FROM hoge;
+----------+
| COUNT(*) |
+----------+
| 17774854 |
+----------+
1 row in set (11.81 sec)
11秒かかってます・・・
設定をすべてデフォルトにしているのでバッファが不十分なのか、それともこれがRocksDBの構造によるオーバーヘッドなのか。
いずれにしろ、本番用途ではチューニングが必要だということはわかりました。
最後に
本記事はMyRocksの知見と事例が増えることを期待して執筆しました。
MySQL5.6からの移行先をMariaDBにするかMySQL5.7にするか検討している企業も多いのではないでしょうか。そのような方々にも参考になれば幸いです。