2014年3月末にMariaDB 10.0.10 GAがリリースされて、並列レプリケーション(Parallel replication)が目玉の1つっぽく書かれているので、簡単に解説。(2014.12.3追記:以下の書籍にも記述した。)
並列レプリケーションとはスレーブ側の機能で、従来はSQLスレッド1つで処理していたrelayログの再生を、複数のスレッドで並列に処理しようというもの。
MySQLにもパラレルworkerという機能があるが、MariaDBのそれとは並列化の粒度が全く異なる。(注:MySQL5.7でMariaDBと同レベルの機能が実装された。)
MariaDBのマスタがコミットしてバイナリログを書く際に、並列実行できるかどうかをバイナリログに書き込んでいる。スレーブはそれに応じて、並列に実行できるSQLは並列に実行する。
具体例をみてみよう。
マスタでbinlog_commit_wait_countとbinlog_commit_wait_usecに適当な値を設定した時の、バイナリログの内容を示す。
.. 略 ... #140312 10:20:07 server id 1 end_log_pos 1045 GTID 1-1-1262369 BEGIN # at 1045 UPDATE test1 SET id = 2 WHERE id = 2 # at 1148 COMMIT # at 1221 #140312 10:20:07 server id 1 end_log_pos 1261 GTID 1-1-1262370 cid=472342 BEGIN # at 1261 UPDATE test1 SET id = 3 WHERE id = 3 # at 1364 COMMIT # at 1437 #140312 10:20:07 server id 1 end_log_pos 1477 GTID 1-1-1262371 cid=472342 BEGIN # at 1477 UPDATE test3 SET id = 1 WHERE id = 1 # at 1580 COMMIT # at 1653 #140312 10:20:07 server id 1 end_log_pos 1693 GTID 1-1-1262372 cid=472342 BEGIN # at 1693 UPDATE test2 SET id = 1 WHERE id = 1 # at 1796 COMMIT # at 1869 #140312 10:20:08 server id 1 end_log_pos 1907 GTID 1-1-1262373 BEGIN # at 1907 UPDATE test1 SET id = 3 WHERE id = 3 ... 略 ...
ここで3つのUPDATE文に、GTIDとともに、"cid=472342"という値が付与されている。
この3つのUPDATE文をよくみると、実行時刻はほぼ同時で、テーブルはそれぞれtest1,test3,test2とバラバラなことがわかる。よって、スレーブはこの3つのUPDATE文を並列に実行できる。
もちろん、マスタは全てのSQLを並列化するのではなく、パラメータで設定した時間(何10〜何100ミリ秒とか)内で並列化できるSQLにだけ、cidを割り当てる。
こんな感じで、MariaDBの並列レプリケーションはマスタとスレーブの協調作業だが、どちらかというとスレーブよりもマスタのほうが賢い。
これに対して、MySQL5.6のスレーブはデータベース毎に並列に実行するだけである。だからMySQLのマスタ側は何も考えない。スレーブがデータベース毎にrelayログの内容を分散してworkerが並列に実行する。
容易にわかるようにMySQL5.6までは、スレーブの並列性?はMariaDBと比較して著しく劣る。
MySQL 5.7で同レベルの機能が実装された。