MariaDB 冗長化

データベースの冗長化は難しいイメージがありましたが、非常に簡単に構築できるようになってきました。
マスタースレーブ型ではスレーブに書き込みできない等の制限がありますが、今回構築する「MariaDB Galera Cluster」というのはクラスター構成で参加ノードは全てマスターとして動作し、どのノードでもデータベースの更新作業を行うことができるという優れものなので試してみました。

MariaDBのアンインストール

MariaDBとMariaDB Galera Clusterは共存できないので、MariaDBのアンインストールが必要です。すでに稼働中の場合はDBのバックアップを取ってからアンインストールします。

# yum remove mariadb-server mariadb

MariaDB Galera Cluster のインストール

MariaDB Galera Cluster用にリポジトリを追加します。
MariaDBの本家サイトにはリポジトリ・ジェネレータが用意されていて、各種ディストリビューション用の最新リポジトリを生成してくれます。
1. Choose a Distro から CentOS
2. Choose a Release から CentOS 7 (x86_64)
3. Choose a Version から 5.5 [Stable]
をそれぞれ選択すると下部に生成されたリポジトリが表示されます。
これをコピーペーストします、/etc/yum.repos.d/MariaDB.repoで作成しました。

# MariaDB 5.5 CentOS repository list - created 2017-12-01 01:11 UTC
# http://downloads.mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/5.5/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

インストールします。

# yum install MariaDB-Galera-server MariaDB-client galera

設定ファイルの準備

MariaDB Galera Clusterを起動するためには、クラスタ設定のための指定をいろいろとしておく必要があり、設定は /etc/my.cnf.d/server.cnf ファイルの [mysqld] セクションに記述します。インストール直後は何も書かれていないので、ここに必要な設定を追記していきます。

# this is only for the mysqld standalone daemon
[mysqld]
wsrep_cluster_name=DBCLUSTER
wsrep_cluster_address=gcomm://[参加させるノードのIPアドレス]
wsrep_node_address=[自ホストのIPアドレス]
wsrep_provider='/usr/lib64/galera/libgalera_smm.so'
wsrep_sst_method=rsync
wsrep_slave_threads=4
default_storage_engine=InnoDB
binlog_format=ROW
innodb_autoinc_lock_mode=2
innodb_locks_unsafe_for_binlog=1

設定ファイルの内容は次の通りです。

   wsrep_cluster_name
   クラスタ名の識別子。クラスタごとに任意の名前を付けてください。
   wsrep_cluster_address
   参加するクラスタ・ノードのIPアドレスを指定します。
  最初のノードでは「gcomm://」とし、IPアドレスを指定しません。
  ただし、設定ファイルに空のアドレス指定をすると再起動のたびに独立したノードを立ち上げてしまいます。
  これはよろしくないので、設定ファイルには隣のノードを明示しておきます。
  なお、ここで指定するノードが起動していないときはエラーになるので注意が必要です。
   wsrep_node_address
   自分のノードアドレスを指定します。明示しないと、最初のNICについているアドレスが自動的に採用されます。指定しなくてもよいのですが、明示しておくことをお勧めします。
   wsrep_provider
   ライブラリファイルをfull pathで指定します。
   wsrep_sst_method
   SSTはState Snapshot Transferといって、ノードをクラスタに追加するときにデータコピーを行う方法を指定します。ここではrsyncを指定しています。
   wsrep_slave_threads
   スレッド数を指定します。マニュアルによればスレッド数の目安は (1) CPUコア数の2倍 (2) 書き込み接続数の1/4、とあります。ここでは適当に4としています。
   DBエンジン設定
   以下の4つの設定は必須です。他のDBエンジンやモードでは動作に問題が生じる可能性があるので気を付けてください。
  default_storage_engine=InnoDB
  binlog_format=ROW
  innodb_autoinc_lock_mode=2
  innodb_locks_unsafe_for_binlog=1

初期ノードを起動する

初期ノードDB1でサービスを起動します。

# service mysql start --wsrep_cluster_address=gcomm://

ファイアウォールでTCP3306、4444、4567の3つのポートを開放する必要があります。

# firewall-cmd --permanent --zone=public --add-port=3306/tcp
success
# firewall-cmd --permanent --zone=public --add-port=4444/tcp
success
# firewall-cmd --permanent --zone=public --add-port=4567/tcp
success
# firewall-cmd --reload

設定の動作確認

# mysql
MariaDB [(none)]> show status like 'wsrep_%';
+------------------------------+--------------------------------------+
| Variable_name                | Value                                | 
+------------------------------+--------------------------------------+
| wsrep_local_state_comment    | Synced};                             |
| wsrep_incoming_addresses     | 192.168.xxx.xxx:3306                 |
| wsrep_evs_state              | OPERATIONAL                          |
| wsrep_cluster_status         | Primary                              |
 ~途中省略しています

チェックポイントは wsrep_local_state_commentSynced になっていることと、wsrep_incoming_addresses自分のノードアドレスが入っていることです。これで自分が初期ノードとして正しく動作していることが確認できます。

自動起動設定

# chkconfig mysql on

ノードを追加

初期ノードが起動したら、次のノードを追加します。ノードの追加は非常に簡単で、初期ノード・サーバと同じように設定を行い、起動するだけです。
初期ノードDB1と同様に、MariaDBのアンインストール・MariaDB Galera Cluster のインストールを行います。

設定ファイルの準備

初期ノードDB1と同様ですがIP欄が逆になるので注意です。

# this is only for the mysqld standalone daemon
[mysqld]
wsrep_cluster_name=DBCLUSTER
wsrep_cluster_address=gcomm://[参加させるノードのIPアドレス]
wsrep_node_address=[自ホストのIPアドレス]
wsrep_provider='/usr/lib64/galera/libgalera_smm.so'
wsrep_sst_method=rsync
wsrep_slave_threads=4
default_storage_engine=InnoDB
binlog_format=ROW
innodb_autoinc_lock_mode=2
innodb_locks_unsafe_for_binlog=1

注意するのはDB1の設定ファイルとIPアドレスが逆になっている点です。
wsrep_cluster_address、wsrep_node_address

追加ノードを起動

いたってシンプルに起動するだけです。

# service mysql start
mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
....SST in progress, setting sleep higher. SUCCESS!

自動起動設定

# chkconfig mysql on

DB冗長化の動作確認

初期ノードDB1でDataBaseを作成してみてください、その後追加ノードDB2でDataBaseの一覧をみると追加されているのが確認できます。

初期ノードDB1

MariaDB [(none)]> create database test;
Query OK, 1 row affected (0.01 sec)

追加ノードDB2

MariaDB [(none)]> show databases;

如何でしょう、とても簡単に冗長化できちゃいました。

MariaDB [(none)]> show status like 'wsrep_incoming_addresses';
+--------------------------+-------------------------------------+
| Variable_name            | Value                               |
+--------------------------+-------------------------------------+
| wsrep_incoming_addresses | 自ホストIP:3306,参加ノードIP:3306    |
+--------------------------+-------------------------------------+
1 row in set (0.00 sec)
 
MariaDB [(none)]>

wsrep_incoming_addressesを確認れば冗長されているノードの確認ができます。

ログ確認

$ cat /var/lib/mysql/`hostname`.err

171201 11:13:50 [Note] WSREP: Quorum results:
       version    = 4,
       component  = PRIMARY,
       conf_id    = 5,
       members    = 2/2 (joined/total),
       act_id     = 13892,
       last_appl. = 13823,
       protocols  = 0/7/3 (gcs/repl/appl),
       group UUID = 9f07f725-xxxx-xxxx-xxxx-4f60761d281a
171201 11:13:50 [Note] WSREP: Flow-control interval: [23, 23]
171201 11:13:50 [Note] WSREP: New cluster view: global state: 9f07f725-xxxx-xxxx-xxxx-4f60761d281a:13892, view# 6: Primary, number of nodes: 2, my index: 0, protocol version 3
171201 11:13:50 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification.
171201 11:13:50 [Note] WSREP: REPL Protocols: 7 (3, 2)
171201 11:13:50 [Note] WSREP: Assign initial position for certification: 13892, protocol version: 3
171201 11:13:50 [Note] WSREP: Service thread queue flushed.
171201 11:13:50 [Note] WSREP: Member 1.0 (WEBDB2) synced with group.
171201 11:13:53 [Note] WSREP: (9f076d26, 'tcp://0.0.0.0:4567') turning message relay requesting off