MySQL Binlog APIを試してみる
MySQL のレプリケーションは素晴らしい仕組みなのですが、ちょっと凝ったことをしようとするには機能が限られています。特に、MySQL の更新を他のデータストアにマイグレーションしたいような時は、Trigger を使って超頑張るのはイマイチで、バイナリログを使ったレプリケーションの仕組みをそのまま拡張してマイグレーションするようなワーカーを書きたくなるものです。
そんな時に使える便利な API として、Binlog API というものがあります。まだ開発途上ではありますが、期待の持てる API です。
試しにどんなもんなのか使ってみました。
追記 2012/07/09
とか言ってたら、さっそく @tokuhirom さんが Perl バインディングを作ってくれました!!!
- tokuhirom/MySQL-BinLog · GitHub
- mysql の binlog api を利用するための Perl Binding を作りました –
"><xmp>TokuLog - tokuhirom's blog.
早速 XS 童貞の私ですがコード読み込んで使ってみようとおもいます!tokuhirom++
各言語のエキスパートのみなさま、引き続き他言語のバインディングもお待ちしています!(ぇ
追記 2012/07/10
antipop さんが Mac での動かし方を紹介してくれています!
準備
CentOS5 系の 64bit で試した手順です。まずビルドに必要なパッケージを入れたいのですが、CentOS の yum レポジトリだと足りないので epel と atrpmas というレポジトリを追加します。
# cat /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 5 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/5/$basearch
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-5&arch=$basearch
failovermethod=priority
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL
# cat /etc/yum.repos.d/atrpms.repo
[atrpms]
name=Redhat Enterprise Linux $releasever - $basearch - ATrpms
baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/stable
enabled=0
gpgcheck=1
gpgkey=http://atrpms.net/RPM-GPG-KEY.atrpms
どちらも enabled=0 にしてるので明示的に enabled しないと yum コマンドが検索しないようにしてます。
あとは yum 実行するだけ。bzr はソースのチェックアウト用、cmake はビルドツール、boost は CentOS の 1.33 だとバージョンが古いので atrpms のものを利用。epel に boost141 ってのがあるのでそれでもいけるのかも(未確認)。
# yum --enablerepo=epel install cmake bzr
# yum --disablerepo=* --enablerepo=atrpms install boost*
ちなみに、atrpms の boost-devel と CentOS-Base の boost-devel はファイル被ってるみたいで、atrpms の 64bit のが入った後に CentOS-Base の 32bit のが入るとビルドできなくなる。キモイだけなので 32bit は入れないのが吉。僕が試した環境は最初から入ってなかった。
ビルド&インストール
簡単。
$ bzr branch lp:mysql-replication-listener
$ cd mysql-replication-listener
$ cmake .
$ make
$ sudo make install
これで/usr/local/include
にいくつかのヘッダファイルと、/usr/local/lib
にライブラリがインストールされます。
example ビルド
ソースの中に example があるのでそれを試してみます。
$ cd example
$ cmake .
$ make
これで basic-[12]を実行したいところなんですが、僕の環境だと実はライブラリのサーチパスに/usr/local/lib
が入ってなかった。こういう場合は、サーチパスに足すか実行時に指定してあげる。
サーチパス追加の場合
$ sudo echo /usr/local/lib >> /etc/ld.so.conf
$ sudo ldconfig
$ ./basic-1
実行時に指定の場合
$ LD_LIBRARY_PATH=/usr/local/lib ./basic-1
or
$ LD_PRELOAD=/usr/local/lib/libreplication.so ./basic-1
Let’s example
では実際に試してみましょう。おもしろいのは basic-2 で master につないで見るのだと思います。自分はとりあえず MySQL::Sandbox で実験。
$ make_replication_sandbox ~/mysql/mysql-5.1.63-linux-x86_64-glibc23.tar.gz
$ cat ~/sandboxes/rsandbox_mysql-5_1_63/master/my.sandbox.cnf
[client]
user = msandbox
password = msandbox
port = 28888
↑確認
$ ./basic-2 'mysql://msandbox:msandbox@127.0.0.1:28888'
SET PASSWORD FOR 'root''''localhost'='*6C387FC3893DBA1E3BA155E74754DA6682D04747'
grant all on *.* to msandbox'''127.%' identified by 'msandbox'
grant all on *.* to msandbox'''localhost' identified by 'msandbox'
grant SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,
SHOW DATABASES,CREATE TEMPORARY TABLES,LOCK TABLES, EXECUTE
on *.* to msandbox_rw'''localhost' identified by 'msandbox'
grant SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,
SHOW DATABASES,CREATE TEMPORARY TABLES,LOCK TABLES, EXECUTE
on *.* to msandbox_rw'''127.%' identified by 'msandbox'
grant SELECT,EXECUTE on *.* to msandbox_ro'''127.%' identified by 'msandbox'
grant SELECT,EXECUTE on *.* to msandbox_ro'''localhost' identified by 'msandbox'
grant REPLICATION SLAVE on *.* to rsandbox'''127.%' identified by 'rsandbox'
delete from user where password=''
delete from db where user=''
flush privileges
おおおおお!!!!普通に binlog が読み込まれて Query が表示されました。しかも、イベントループに入っていて、新しい binlog を待ち構えています。では、別クライアントから更新文を発行してみます。
$ ~/sandboxes/rsandbox_mysql-5_1_63/master/use
> use test
> create table t1 (id int unsigned not null auto_increment, value varchar(255), primary key (id)) engine=InnoDB;
> begin;
> insert into t1 (value) values ("aaaa");
> insert into t1 (value) values ("bbbb");
> commit;
すると、先程の basic-2 の方に DDL が流れてくるのが見えると思います。トランザクションは当然 commit して初めて流れてきます(basic-2 が COMMIT は print してくれてないっぽい)。
create table t1 (id int unsigned not null auto_increment, value varchar(255), primary key (id)) engine=InnoDB
BEGIN
insert into t1 (value) values ("aaaa")
insert into t1 (value) values ("bbbb")
まとめ
というわけで、単に example を動かしてみただけですが、かなり夢が広がりますね。
しかし、C++力がない!願わくは、ワーカーっぽいものは LL で書きたい(既存アプリのライブラリが使えたりするでしょうし)ので、Binlog API の各種 LL へのバインディングが欲しいところです。誰か書いて!もしくは書き方教えて!
あと Mac で boost の使い方がよく分からなかったので、Mac で動いた人いたら動かし方教えてください><
参考
- CentOS で EPEL や ATrpms のパッケージを yum で利用できるようにする
- Replication Booster for MySQL を試す – blog.nomadscafe.jp
-
とおりすがり 12-07-09 (月) 10:59
手元だとなぜか examples/CMakeFiles/basic-2.dir/link.txt に -lboost_system を追加しないとうごきませんでした(ubuntu)。
-
riywo 12-07-10 (火) 0:33
情報ありがとうございます!