長年の議論に終止符 -- MySQLとMariaDBの違い一覧

(2014.12.3追記:このblogの内容は、以下の書籍にも反映させた。)

SQLレベルの差異

MariaDB5.5とMySQL5.5ではSQLレベルでの違いはほとんどなかった。autoincrementの最大値の扱いくらい。
ただし、MariaDB10.0でREGEXPがマルチバイト対応になったので、アプリ側は注意。

項目 MySQL MariaDB
Autoincrement 最大値に達すると、以降は最大値を繰り返す。Warningのみ。エラーにならない。tinyintなら…,125,126,127,127,127… 最大値-1まで。以降はエラーを返す。tinyintなら…,125,126,ERROR,ERROR,…
EXPLAIN文 JSON形式 バージョン5.6から 未対応
Optimizer Trace バージョン5.6から 未対応(ただし、MariaDBのほうがオプティマイザもエクゼキュータも賢い。オプティマイザ比較はこちらを参照。)
インデックス形式 BTREE,HASH BTREE,HASH,RTREE
BLOB tinyblob,blob,mediumblob,longblob blobのみ
REGEXP マルチバイトに未対応 MariaDB 10.0からマルチバイトセーフ(バージョンアップ時にはアプリ側で注意が必要)


MySQL5.6、同5.5、MariaDB10.0、同5.5は全て同じ通信プロトコルで話をする。ミドルウエアやWEBアプリケーションなどユーザレベルではあまり苦労せず移行できるはずだが、
MySQL 5.7など徐々にバージョンが進むにつれて移行に手間がかかるようになるだろう。

機能面の差異

バージョン5.5どうしで比較すると、MariaDB5.5 = MySQL5.5コミュニティ版 + (スレッドプール+プランナ改良)という関係になっている。

スレッドプール

MySQLは商用(Enterprise)版のみだが、MariaDBは標準でサポート。WEB系で簡単なSQLしか実行しないならスレッドプールは最強のはず。正直、これだけでもMariaDBに移行する価値があると思う。


optimizer_switch

MariaDBのoptimizer_swtichMySQLのoptimizer_switch

こういう基本的な部分がMySQLはとてもプア。MariaDB(とPostgreSQL)とのオプティマイザ比較はこちらを参照。ver5.7でちょっとマシになったようだけれど、しょせん「当社比」みたいな。MySQLの百花繚乱的な新機能追加も、こういった基盤のプアな部分がみえてしまうとなんだかなーと感じ。
商用との差別化をせざるをえないとはいえ有償スレッドプールとか、いろいろと開発バランスの悪さが透けて見えてくる。

ちょっと違うけどMariaDBはインデックスにBTREE,HASHの他にRTREEもサポート。

バイナリログ

MySQL5.6はRBLで圧縮機能*1がついた。この新しいフォーマット名をversion2と呼び、従来のフォーマットをversion1と呼ぶ。ただしデフォルトはSBLなので普通に使う分には影響なし。
MariaDBはversion1のみ。

UNDOログ

MariaDB 10.0/MySQL5.6でテーブルスペースからUNDOログを分離。またpurgeスレッドも任意の数だけ起動できる。

INNODB

トランザクションログの書き込み(flush)に関しては(バイナリログの書き込みと絡んで)重大な違いがある。これに関しては、諸々が落ち着いたら書くつもり。 → ということで書いた

レプリケーション

MySQLは5.6からパラレルworker、MariaDBは10.0からパラレルレプリケーション(並列レプリケーション)。
目的は同じだけど、MySQL 5.6とMariaDB 10.0で比較すると、完成度や有効性はMariaDBの並列レプリケーションの圧勝。
詳細は"MariaDBの並列レプリケーション"に書いたので、こちらを参照のこと。
(MySQL 5.7でMariaDB同様のことができるようになったらしい。)


MariaDB 10.0は、マルチソースレプリケーションと称して、スレーブが複数のマスタを持つことができる(CHANGE MASTERで複数のマスタを設定するだけ)。
MySQLは5.7でサポート。


GTIDも違う。

MySQLのGTID = `UUID`:transaction_id

MariaDBのGTID = `gitd_domain_id`-`server_id`-transaction_id

transaction_idは共通で、1から割り当てられる整数。

MySQLのUUID(Universally Unique Identifier)は自動割当て。
MariaDBのgitd_domain_idはレプリケーションするサーバクラスタ毎に手動で割り振る。server_idは従来と同じ。

MariaDBって

MySQLからフォークしたプロダクトで、SUNを退職したMySQL創業者のMichael "Monty" Wideniusが作っている。
MySQLの最新機能を少しずつ取り込みながら*2、セキュリティや頑健性や性能を高めている。

バージョン ベースのシステム 説明
10.0(αバージョン) MariaDB 5.5 MariaDB5.5をベースにMySQL5.6の機能をバックポートし、さらに独自機能追加したバージョン。まだα
5.5(現時点での最新版) MySQL 5.5 2012年4月リリース。MySQL 5.5をベースに独自機能追加したバージョン
5.3 MariaDB 5.2 20012年2月リリース。MariaDB5.2を改良したバージョン
5.2 MySQL 5.1 2010年11月リリース。MySQL 5.1をベースに再度フォークしたバージョン
5.1 MySQL 5.1 2010年2月リリース。MySQL 5.1をベースに独自機能追加したバージョン


MariaDBバージョン5.1はMySQLバージョン5.1をベースに独自機能や改良を行ったもので、 MySQLバージョン5.5のリリースが難航している間にMariaDBバージョン5.2と5.3がリリースされた。


MariaDBバージョン5.5はMySQLバージョン5.5をベースに独自機能や改良を行ったバージョンで、表面上の機能の違いは軽微でほぼ完全な互換性を有しているが、ソースコードを比較するとメモリーリークの対処や非常に細かなエラー処理など、頑健性を高める改善が数多くなされていることがわかる*3


MySQLバージョン5.6は内部的に大規模なリファクタリングが行われたので これをベースに改めてMariaDB独自の改善を加えることは困難となった。そこでMariaDBの5.5に続く新バージョンは、MariaDBバージョン5.5をベースにMySQLバージョン5.6の新機能から必要と判断した部分を取り込み*4、さらにMariaDB独自機能を追加する方針で開発することになった。それに伴いバージョン番号を一挙に10.0に引き上げた。


ということでMySQLMariaDBの内部は、今後どんどん違ったものになっていく。


長年の議論に終止符を打つ。MariaDBが出てはや数年、未だにMySQLMariaDBか迷っているなら、それは双方ともネガティブな理由が存在するということなのだから、PostgreSQLに移りませう。


バージョンアップ毎にバッドノウハウに振り回されるのは本末転倒。GPLライセンスが問題になる場合も、PostgreSQLならBSD風ライセンスで安心。

*1:データそのものの圧縮ではなく、それまで変更前後の全レコードデータを書き込んでいたのを、変更されたカラムのみ書き込むことでデータ総量を圧縮する。

*2:取り込むばかりではない。例えばバイナリログのchecksumはMariaDBの機能をMySQLが取り込んだ。

*3:最終的にMariaDBバージョン5.5とMySQLバージョン5.5の違いはソースコードレベルで61[Mbyte]

*4:正確には「全てを取り込む」とも「選択的に取り込む」ともアナウンスされていない。現実問題として全て取り込むのは不可能だろうし、5.5の段階でほどほど使えるのだから、MySQL5.6以降の全てを取り込む意味もないだろう。ゴテゴテした新機能を追求するより、ユーザからのフィードバックを取り込んでいくプロダクトを選ぶのが、そもそもオープンソースを使う意味だったはず。