2014年1月23日木曜日

Galera Arbitratorというもの(garbd)

Galera Cluster(俺が実際に色々やってるのはPercona XtraDB Cluster)はスプリットブレイン対策としてQuorum方式を採用している。クラスターを構成するノードの *過半数* とコミュニケーションが取れていない場合、自身がネットワークから切り離されているとみなして *全ての操作を* 拒否するようになる。Galera Clusterはそもそも全てのノードのデータが「仮想完全同期」されているという前提でマルチマスターのトポロジーを提供しているため、コミュニケーションパスが途切れて同期できていないかもしれない状態は、マルチマスターを提供するための下地が崩れるからこうなっている。

mysql> use test
ERROR 1047 (08S01): Unknown command

mysql> SELECT * FROM d1.t1;
ERROR 1047 (08S01): Unknown command

出力はこんな感じで、何をしてもError: 1047のUnknown commandが返ってくるようになる。流石にmysqlコマンドラインクライアントだけで完結するコマンド(helpとかcharsetとかteeとか)は実行できるけど、サーバー側から情報を引っ張って何かするコマンド(statusとuseくらい?)は実行できなくなる。

で、コミュニケーションパスが生きている必要があるノードはクラスターを構成するノードの *過半数* なので、2台構成にしてしまうと1台お亡くなりになった時に 残った1台> 2* 50% が成り立たないため、生き残った1台はこの状態に突入する。これを避けるために、Galera Clusterは最低3台での構成を推奨 している。

SET GLOBAL wsrep_provider_options= 'pc.ignore_sb= ON'; という手もあるけれど(名前の通り、スプリットブレイン状態になっててもコマンドを拒否しなくなる)、本当にネットワークがおかしくなった時に何が起こるかわからない(2つのmysqldそれぞれに矛盾する更新がかかったら、とか、更新が伝達されずにレコードを読んじゃったら、とか)ので、あまりやりたくない。かといって物理サーバー3台…うーん、微妙。

そんなわたしに贈る、Galera Arbitrator。プロセス名はgarbd。

$ ll /usr/local/mysql5534_pxc/bin/garbd
-rwxr-xr-x 1 root root 18015250 12月  2 21:20 /usr/local/mysql5534_pxc/bin/garbd

Percona XtraDB Cluster 5.5.34の.tar.gzのバイナリーを解凍した版にはbinの下に入ってた。ソースからコンパイルした人にはいない。どこから手に入れるのかもよく判らないけど、ソースからコンパイルした人、libの下にlibgalera_smm.soもなくて別途codershipから取ってきて入れないといけないから、そこから入れるのかな。PXCなら.tar.gz版がオールインワンで扱いやすいと思う余談。MariaDB Galera Clusterは(入ってるのか入ってないのか)知らない。

$ /usr/local/mysql5534_pxc/bin/garbd --help

Usage: /usr/local/mysql5534_pxc/bin/garbd [options] [group address]

Configuration:
  -d [ --daemon ]       Become daemon
  -a [ --address ] arg  Group address
  -g [ --group ] arg    Group name
  --sst arg             SST request string
  --donor arg           SST donor name
  -o [ --options ] arg  GCS/GCOMM option list
  -l [ --log ] arg      Log file
  -c [ --cfg ] arg      Configuration file


Other options:
  -v [ --version ]      Print version
  -h [ --help ]         Show help message

FATAL: Exit

ざっくりと、必要最低限っぽいオプションは-a(PXCのwsrep_cluster_addressに相当)と-g(PXCのwsrep_cluster_nameに相当)かしら。

$ /usr/local/mysql5534_pxc/bin/garbd -a "gcomm://xxx.xxx.xxx.xxx:13333" -g "cluster_name" -o "gmcast.listen_addr= tcp://0.0.0.0:13334"
2014-01-23 12:13:20.944  INFO: Read config:
        daemon:  0
        address: gcomm://xxx.xxx.xxx.xxx:13333
        group:   cluster_name
        sst:     trivial
        donor:
        options: gmcast.listen_addr= tcp://0.0.0.0:13334; gcs.fc_limit=9999999; gcs.fc_factor=1.0; gcs.fc_master_slave=yes
        cfg:
        log:

2014-01-23 12:13:20.952  INFO: protonet asio version 0
2014-01-23 12:13:20.953  INFO: backend: asio
2014-01-23 12:13:20.967  INFO: GMCast version 0
2014-01-23 12:13:20.972  INFO: (50019916-83dc-11e3-a310-bfb42459a728, 'tcp://0.0.0.0:13334') listening at tcp://0.0.0.0:13334
2014-01-23 12:13:20.972  INFO: (50019916-83dc-11e3-a310-bfb42459a728, 'tcp://0.0.0.0:13334') multicast: , ttl: 1
2014-01-23 12:13:20.992  INFO: EVS version 0
2014-01-23 12:13:21.000  INFO: PC version 0
2014-01-23 12:13:21.000  INFO: gcomm: connecting to group 'cluster_name', peer 'xxx.xxx.xxx.xxx:13333'
2014-01-23 12:13:21.007  INFO: (50019916-83dc-11e3-a310-bfb42459a728, 'tcp://0.0.0.0:13334') turning message relay requesting on, nonlive peers: tcp://xxx.xxx.xxx.xxx:13332
2014-01-23 12:13:21.489  INFO: (50019916-83dc-11e3-a310-bfb42459a728, 'tcp://0.0.0.0:13334') turning message relay requesting off
2014-01-23 12:13:21.505  INFO: declaring 1663d468-79c2-11e3-a5e5-2f016f2db075 stable
2014-01-23 12:13:21.505  INFO: declaring bc9b8196-83d6-11e3-b4d0-1a4766eec11e stable
2014-01-23 12:13:21.506  INFO: Node 1663d468-79c2-11e3-a5e5-2f016f2db075 state prim
2014-01-23 12:13:21.506  INFO: view(view_id(PRIM,1663d468-79c2-11e3-a5e5-2f016f2db075,43) memb {
        1663d468-79c2-11e3-a5e5-2f016f2db075,
        50019916-83dc-11e3-a310-bfb42459a728,
        bc9b8196-83d6-11e3-b4d0-1a4766eec11e,
} joined {
} left {
} partitioned {
})
2014-01-23 12:13:22.005  INFO: gcomm: connected
2014-01-23 12:13:22.005  INFO: Changing maximum packet size to 64500, resulting msg size: 32636
2014-01-23 12:13:22.005  INFO: Shifting CLOSED -> OPEN (TO: 0)
2014-01-23 12:13:22.005  INFO: Opened channel 'cluster_name'
2014-01-23 12:13:22.006  INFO: New COMPONENT: primary = yes, bootstrap = no, my_idx = 1, memb_num = 3
2014-01-23 12:13:22.006  INFO: STATE EXCHANGE: Waiting for state UUID.
2014-01-23 12:13:22.006  INFO: STATE EXCHANGE: sent state msg: 5055781a-83dc-11e3-b9e1-e2687a7bb5a6
2014-01-23 12:13:22.006  INFO: STATE EXCHANGE: got state msg: 5055781a-83dc-11e3-b9e1-e2687a7bb5a6 from 0 (xxxx_3333)
2014-01-23 12:13:22.006  INFO: STATE EXCHANGE: got state msg: 5055781a-83dc-11e3-b9e1-e2687a7bb5a6 from 2 (xxxx_3332)
2014-01-23 12:13:22.007  INFO: STATE EXCHANGE: got state msg: 5055781a-83dc-11e3-b9e1-e2687a7bb5a6 from 1 (garb)
2014-01-23 12:13:22.007  INFO: Quorum results:
        version    = 2,
        component  = PRIMARY,
        conf_id    = 33,
        members    = 2/3 (joined/total),
        act_id     = 29266,
        last_appl. = -1,
        protocols  = 0/4/2 (gcs/repl/appl),
        group UUID = 64863b36-62f7-11e3-bef2-a746941be182
2014-01-23 12:13:22.007  INFO: Flow-control interval: [9999999, 9999999]
2014-01-23 12:13:22.007  INFO: Shifting OPEN -> PRIMARY (TO: 29266)
2014-01-23 12:13:22.007  INFO: Sending state transfer request: 'trivial', size: 7
2014-01-23 12:13:22.007  INFO: Node 1 (garb) requested state transfer from '*any*'. Selected 0 (xxxx_3333)(SYNCED) as donor.
2014-01-23 12:13:22.007  INFO: Shifting PRIMARY -> JOINER (TO: 29266)
2014-01-23 12:13:22.008  INFO: 0 (xxxx_3333): State transfer to 1 (garb) complete.
2014-01-23 12:13:22.008  INFO: 1 (garb): State transfer from 0 (xxxx_3333) complete.
2014-01-23 12:13:22.008  INFO: Shifting JOINER -> JOINED (TO: 29266)
2014-01-23 12:13:22.008  INFO: Member 0 (xxxx_3333) synced with group.
2014-01-23 12:13:22.008  INFO: Member 1 (garb) synced with group.
2014-01-23 12:13:22.008  INFO: Shifting JOINED -> SYNCED (TO: 29266)

"gmcast.listen_addr= tcp://0.0.0.0:13334"は、このノード既にPXCが3インスタンスいるのでポートがカブらないように調整しているだけで、フツーにPXCのmysqldを起動させた時と同じように、コミュニケーションパスを使って自分のステータスをSYNCEDまで持って行ってる。SST(=フル同期)はしない。

他のノードからSHOW GLOBAL STATUS LIKE 'wsrep_cluster_size'で見ると、確かに増えている。これでmysqldが3つなくても、1台落ちただけなら過半数を満たせる数が確保できるという算段。APサーバーの先頭か何かにgarbdだけ入れておけばね。


……MHA-Managerみたい。。

0 件のコメント :

コメントを投稿