MariaDB Galera Cluster 構築ポイント

# はじめに
MariaDB Galera Clusterでマルチマスタレプリケーションが組みたいみなさんこんにちは。

先週検証のため0から構築したので、ポイントだけ残しておきます。

# 環境情報
OSはCentOS 6.9です。MariaDBやgaleraのバージョンは以下の通りですが、他のバージョンでも同じだと思います。

```shell-session
[root@mariadb10-1 ~]# rpm -qa | grep -e Maria -e galera
MariaDB-compat-10.2.10-1.el6.x86_64
galera-25.3.20-1.rhel6.el6.x86_64
MariaDB-common-10.2.10-1.el6.x86_64
MariaDB-client-10.2.10-1.el6.x86_64
MariaDB-server-10.2.10-1.el6.x86_64
```

# yum
yumで簡単にインストールできます。repoファイルを作成しましょう。urlのバージョンを変えれば別のバージョンも簡単にインストールできます。

```ini:/etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2.10/centos6-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
```

# iptables
Galera Clusterを組むためには、MariaDBの接続ポートである3306の他、3つのportを使うので解放が必要です。

```:/etc/sysconfig/iptables
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3333 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 4444 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 4567 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 4567 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 4568 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
```

記載したら再起動しましょう。

なおポートの用途については公式で解説されています。

[Galera Cluster - FIREWALL SETTINGS](http://galeracluster.com/documentation-webpages/firewallsettings.html)

4567がgaleraのreplicationのためのportとあるけど、お互いを検知したりするのに使うのかな。4568はIST、4444がSSTですね。

ISTとSSTについては[Galera Cluster -
 STATE TRANSFERS](http://galeracluster.com/documentation-webpages/statetransfer.html)を参照ください。

```
# service iptables restart
iptables: チェインをポリシー ACCEPT へ設定中filter         [  OK  ]
iptables: ファイアウォールルールを消去中:                  [  OK  ]
iptables: モジュールを取り外し中:                          [  OK  ]
iptables: ファイアウォールルールを適用中:                  [  OK  ]
```

# config

IPアドレスは適当にマスクしました。適宜書き換えください。

```ini:/etc/my.cnf
#
# This group is read both both by the client and the server
# use it for options that affect everything
#
[client-server]

[mysqld]
wsrep_on = ON

wsrep_cluster_address = 'gcomm://192.168.XX.10,192.168.XX.11,192.168.XX.12'
wsrep_cluster_name = galera_cluster
wsrep_sst_auth = ''
wsrep_sst_method = rsync
wsrep_slave_threads = 8
wsrep_node_address = 192.168.XX.10
wsrep_node_incoming_address = 192.168.XX.10

binlog_format = ROW
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
innodb_locks_unsafe_for_binlog = 1

wsrep_auto_increment_control = ON
wsrep_drupal_282555_workaround = ON
wsrep_retry_autocommit = 10

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
```

* [wsrep_on](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_on)はv10.1からdefault OFFになりました。サービス起動後クラスタに組み込むためにはONにする必要があります。前のバージョンからupgradeする蔡には気を付けてください。
* [wsrep_cluster_address](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_cluster_address)はクラスタを構成するノードのIPアドレスです。同期をつなぎにいく相手なので自ノードは含まれなくても良いのですが、含んでいても問題はなさそうなので全ノード同じにしています。
* [wsrep_cluster_name](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_cluster_name)はクラスタを識別する名前です。同一クラスタでは同一の名前をつける必要があります。
* [wsrep_sst_auth](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_sst_auth)はreplication時の認証です。methodがrsyncの場合は不要ですし、デフォルト値がemptyなので明に指定する必要ありませんね。
* [wsrep_sst_method](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_sst_method)はSSTで使う手段。rsyncの他にxtrabackup、mysqldumpが使えます。最近だとmariadumpってのもあるんですね。初めて知った。
* [wsrep_slave_threads](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_slave_threads)は同期を行うときのスレッド数で、多いほうが早くなります。デフォルトの1から変える場合、CPUコア数の2倍か、クライアントの接続数の1/4を目安にするといいでしょう。一貫性の問題が発生する場合は1にするといいかもしれません。
* [wsrep_node_address](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_node_address)はノードのnetworkアドレスです。自動で推測させるより指定しましょう。
* [wsrep_node_incoming_address](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_node_incoming_address)はアクセスを受け付けるnetworkアドレス。こちらも指定しましょう。
* [binary-log-formats](https://mariadb.com/kb/en/library/binary-log-formats/)は、binlogを出力しなければ必要ありません。ROW(行)ベースが望ましく、STATEMENTを使う理由はほぼないと思います。MIXEDが理想的かもしれませんが、影響を詳細に見てないのでROWにしています。
* [default_storage_engine](https://mariadb.com/kb/en/library/server-system-variables/#default_storage_engine)はそのまま、デフォルトのストレージエンジンです。5.5からはデフォルトがinnodbになったので、これも明に指定不要です。
* [innodb_autoinc_lock_mode](https://mariadb.com/kb/en/library/xtradbinnodb-server-system-variables/#innodb_autoinc_lock_mode)は自動的にidをincrementする(AUTOINC)する際の、ロックの方式を指定します。0は従来型のロックで、変更の際は全てロックをかけます。1はINSERTなど全体のレコード量が分からないときにロックをかけ、最後のレコードからインクリした値をつけます。2はロックを取得せず、IDも離散した値になります。ロックをかけないため性能は向上しますが、STATEMENTベースでのレプリケーションができません。ROWベースのレプリケーションを用いましょう。
    * 参考：[第49回　MySQLのAUTO_INCREMENTについて](http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0049)
* [innodb_locks_unsafe_for_binlog](https://mariadb.com/kb/en/library/xtradbinnodb-server-system-variables/#innodb_locks_unsafe_for_binlog)は分離レベルRepeatable Readを実現するために[Gap Locking](https://mariadb.com/kb/en/library/xtradbinnodb-lock-modes/#gap-locks)という方法を取る。10.0からはDeprecatedになっているので、代わりにRead Committedの分離レベルを使えとのこと。
* [wsrep_auto_increment_control](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_auto_increment_control)をONにすると、ノードが追加されたときにauto_increment_incrementと auto_increment_offsetが変更される。これはマルチマスタレプリケーションを行うとき、ノード数分offsetを取っておかないとレコード挿入の際に衝突するからである。
    * 参考：[MariaDB Galera Cluster での AUTO_INCREMENT の扱いについて](https://blog.neoflow.jp/oss/mariadb-galera-cluster/2408/)
    * 参考：[[翻訳] "Tips on Converting to Galera"（Galeraに移行する際のポイント）](https://qiita.com/kakuka4430/items/5b0862547d5ea4a3d60d) 
* [wsrep_drupal_282555_workaround](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_drupal_282555_workaround)はバグを回避するためのオプション。
* [wsrep_retry_autocommit](https://mariadb.com/kb/en/library/galera-cluster-system-variables/#wsrep_retry_autocommit)はクラスタ内で競合が発生した場合、コミットをリトライする回数。

# 1台目起動
--wsrep-new-clusterオプションをつけて、同期相手を探しにいかないようにしましょう。

参考：[Galera Cluster Documentation)STARTING THE CLUSTER](http://galeracluster.com/documentation-webpages/startingcluster.html)

# 2台目以降の起動
通常通り起動すれば加入します。

# 加入後の確認
クラスタサイズ、およびクラスタのuuidを確認し、全ノードで同じになっていればokです。

```
# mysql -uroot -e "show status like 'wsrep_cluster%';"
+--------------------------+--------------------------------------+
| Variable_name            | Value                                |
+--------------------------+--------------------------------------+
| wsrep_cluster_conf_id    | 1                                    |
| wsrep_cluster_size       | 1                                    |
| wsrep_cluster_state_uuid | aea89f03-087e-11e6-9b46-3e58a457dd6a |
| wsrep_cluster_status     | Primary                              |
+--------------------------+--------------------------------------+
```

wsrep_cluster_conf_idはクラスタの状態が変わるたびにインクリメントされます。

参考：[Galera Cluster Documentation)MONITORING CLUSTER STATUS](http://galeracluster.com/documentation-webpages/monitoringthecluster.html)

# おわりに
confの解説がメインになりましたが、galera clusterはわりと簡単に構築できます。configも最低限必要なものはcluster_name、同期先や自分のアドレスぐらいです。

それではよいGalera Clusterライフを！