Master-Slave 構成の MariaDB を構築する手順について解説します。Master-Slave 構成の制御は Pacemaker を使い、自動的に Master-Slave を切り替えられる構成を目指します。
最近のバージョンの Pacemaker Version 2.1系は微妙にコマンドが異なっていたり、MasterがPromoteへ名前も変わっているので、最新の状況を反映してまとめました。
以下の設定の前提で行います。
- OS: Ubuntu 22.04
- VIP: 192.168.56.10
- Host1: host1(192.168.56.21)
- Host2: host2(192.168.56.21)
- Replication User: repl
- replication password: password
- Test User: monitoring
- Test Password: password
手順
MariaDB のインストール
MariaDB Server を2台のサーバにインストールします。
sudo apt install -y mariadb-server
MariaDBの設定
MariaDB の設定ファイルを編集し、レプリケーションの設定を行います。
sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf
50-server.cnf に以下の設定を行います。レプリケーションをするための設定です。 server-id の行はコメントアウトして、2台のサーバにそれぞれ異なる値を設定します。 また、bind-address は、使用するネットワーク環境に合わせ、外部から接続を受けられるネットワークのIPアドレスに変更してください。 以下の設定例は、すべてのネットワークアドレスから接続を受け付ける設定です。
bind-address: 0.0.0.0 # The following can be used as easy to replay backup logs or for replication. # note: if you are setting up a replication slave, see README.Debian about # other settings you may need to change. server-id = 1 # この行をコメントアウトし、server idを設定 log_bin = /var/log/mysql/mysql-bin.log # この行をコメントアウト expire_logs_days = 10 max_binlog_size = 100M
Replication ユーザ/監視ユーザの作成
host1で作業します。mysql コマンドを使い root ユーザでログインして、ユーザを作成します。
replication userの作成。ユーザ名は、"repl@%"、パスワードは、"password"としています。注意として、本番では、このパスワードは破られやすいので使わないほうが良いでしょう。
CREATE USER 'repl'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repl'@'%'; CREATE USER 'repl'@'localhost' IDENTIFIED BY 'password'; GRANT SUPER, PROCESS, RELOAD ON *.* TO 'repl'@'localhost'; GRANT SELECT ON performance_schema.* TO 'repl'@'%';
monitoring user の作成。ユーザ名は、"monitoring@%"、パスワードは、"password"としています。
CREATE USER 'monitoring'@'%' IDENTIFIED BY 'password'; GRANT select ON mysql.user TO 'monitoring'@'%';
ユーザ作成後、mysql はブート時に自動起動しないようにし、停止させます。
sudo systemctl disable mariadb sudo systemctl stop mariadb
データをコピー
レプリケーションをするので、host1 の MariaDB のデータを host2 にコピーします。このとき必ず、MariaDB を停止させた状態で行います。 先ほど作成したユーザも一緒にコピーされます。
sudo tar cfc mysql.tar /var/lib/mysql
作成された mysql.tar を host2 に持っていき、展開します。展開するときは以下のようにして行います。 mariadb を停止した状態で行います。
cd / sudo tar xvf mysql.tar
host2も、MariaDB の設定ファイルの変更と、サービス再起動の無効化設定を忘れないようにしてください。
Pacemaker のインストール
クラスタの管理を行う Pacemaker のインストールを行います。
sudo apt install -y pacemaker pcs haveged resource-agents fence-agents
Corosync の設定
Pacemaker は、内部的に Corosync という管理システムを使っています。その設定を行います。
Corosync の Key を作成
sudo corosync-keygen -l
生成したキーを別ホストにコピー
/etc/corosync/authkey を、もう一台の別ホストの同じディレクトリ、ファイル名でコピーします。
/etc/corosync/corosync.conf の設定
Corosync の設定を行います。Corosync はデフォルトでマルチキャストを使い他のサーバと通信しますが、今回の設定はマルチキャスが使えない環境で使用するため、ユニキャストで使用する場合の設定例となります。
この設定は、2台のホストで同じです。
設定のポイント
- host1/host2に同じ設定を行う
- totem-transportにudpuを指定する
- totem-interface-bindnetaddr に接続するネットワークインターフェイスアドレスに設定
- nodelist-node の設定を、各ホスト向けに設定
# Please read the corosync.conf.5 manual page totem { version: 2 # Corosync itself works without a cluster name, but DLM needs one. # The cluster name is also written into the VG metadata of newly # created shared LVM volume groups, if lvmlockd uses DLM locking. # It is also used for computing mcastaddr, unless overridden below. cluster_name: ubuntu # How long before declaring a token lost (ms) token: 3000 # How many token retransmits before forming a new configuration token_retransmits_before_loss_const: 10 # Limit generated nodeids to 31-bits (positive signed integers) clear_node_high_bit: yes # crypto_cipher and crypto_hash: Used for mutual node authentication. # If you choose to enable this, then do remember to create a shared # secret with "corosync-keygen". # enabling crypto_cipher, requires also enabling of crypto_hash. # crypto_cipher and crypto_hash should be used instead of deprecated # secauth parameter. # Valid values for crypto_cipher are none (no encryption), aes256, aes192, # aes128 and 3des. Enabling crypto_cipher, requires also enabling of # crypto_hash. crypto_cipher: none # Valid values for crypto_hash are none (no authentication), md5, sha1, # sha256, sha384 and sha512. crypto_hash: none # Optionally assign a fixed node id (integer) # nodeid: 1234 transport:udpu # interface: define at least one interface to communicate # over. If you define more than one interface stanza, you must # also set rrp_mode. interface { # Rings must be consecutively numbered, starting at 0. ringnumber: 0 # This is normally the *network* address of the # interface to bind to. This ensures that you can use # identical instances of this configuration file # across all your cluster nodes, without having to # modify this option. bindnetaddr: 192.168.56.0 # Corosync uses the port you specify here for UDP # messaging, and also the immediately preceding # port. Thus if you set this to 5405, Corosync sends # messages over UDP ports 5405 and 5404. mcastport: 5405 # Time-to-live for cluster communication packets. The # number of hops (routers) that this ring will allow # itself to pass. Note that multicast routing must be # specifically enabled on most network routers. ttl: 1 } } nodelist { node { name: host1 ring0_addr: 192.168.56.21 nodeid: 1 } node { name: host2 ring0_addr: 192.168.56.22 nodeid: 2 } } logging { # Log the source file and line where messages are being # generated. When in doubt, leave off. Potentially useful for # debugging. fileline: off # Log to standard error. When in doubt, set to no. Useful when # running in the foreground (when invoking "corosync -f") to_stderr: no # Log to a log file. When set to "no", the "logfile" option # must not be set. to_logfile: no #logfile: /var/log/corosync/corosync.log # Log to the system log daemon. When in doubt, set to yes. to_syslog: yes # Log with syslog facility daemon. syslog_facility: daemon # Log debug messages (very verbose). When in doubt, leave off. debug: off # Log messages with time stamps. When in doubt, set to on # (unless you are only logging to syslog, where double # timestamps can be annoying). timestamp: on logger_subsys { subsys: QUORUM debug: off } } quorum { # Enable and configure quorum subsystem (default: off) # see also corosync.conf.5 and votequorum.5 provider: corosync_votequorum expected_votes: 2 }
設定後、corosyncを再起動します。
sudo systemctl restart corosync
Pacemakerの設定
クラスタ管理設定を行います。
Pacemaker初期化
事前に、haclusterユーザのパスワードを、host1/host2それぞれ設定しておきます。
sudo passwd hacluster
パスワードを設定したら、以降、host1のみで操作を行います。
sudo pcs cluster auth -u hacluster -p <password>
ここまで設定すると、pacemakerの状態は以下のようになります。
vagrant@host1:~$ sudo pcs status Cluster name: ubuntu WARNINGS: No stonith devices and stonith-enabled is not false Cluster Summary: * Stack: corosync * Current DC: host2 (version 2.1.2-ada5c3b36e2) - partition with quorum * Last updated: Fri Jun 16 01:35:51 2023 * Last change: Fri Jun 16 01:32:29 2023 by hacluster via crmd on host2 * 2 nodes configured * 0 resource instances configured Node List: * Online: [ host1 host2 ] Full List of Resources: * No resources Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled
基本設定
以降、Pacemaker 関係の設定は host1 のみで行います。
sudo pcs property set stonith-enabled=false sudo pcs property set no-quorum-policy=ignore
自動フェイルバックなし
sudo pcs resource defaults update resource-stickiness="INFINITY" migration-threshold="1"
クラスタリソース設定
IP Resource
準備
sudo pcs node standby host2 sudo pcs cluster cib mysql_repl
IPResource作成
sudo pcs -f mysql_repl resource create ClusterIP IPaddr2 \ ip="192.168.56.10" \ cidr_netmask="24" \ op start timeout="60s" interval="0s" on-fail="restart" \ op monitor timeout="60s" interval="10s" on-fail="restart" \ op stop timeout="60s" interval="0s" on-fail="block"
MySQL Resource
MySQL Resourceの作成を行います。 replication_passwd/test_passwdの設定は、replicationユーザ/monitoringのパスワードに変更すること
sudo pcs -f mysql_repl resource create mysql ocf:heartbeat:mysql sudo pcs -f mysql_repl resource update mysql binary=/usr/bin/mysqld_safe sudo pcs -f mysql_repl resource update mysql datadir=/var/lib/mysql sudo pcs -f mysql_repl resource update mysql log=/var/log/mysql/error.log sudo pcs -f mysql_repl resource update mysql pid=/var/run/mysqld/mysqld.pid sudo pcs -f mysql_repl resource update mysql socket=/var/run/mysqld/mysqld.sock sudo pcs -f mysql_repl resource update mysql replication_user=repl sudo pcs -f mysql_repl resource update mysql replication_passwd=password sudo pcs -f mysql_repl resource update mysql test_user=monitoring sudo pcs -f mysql_repl resource update mysql test_passwd=password sudo pcs -f mysql_repl resource update mysql evict_outdated_slaves=false sudo pcs -f mysql_repl resource update mysql max_slave_lag=60 sudo pcs -f mysql_repl resource update mysql op start interval=0 timeout=120s sudo pcs -f mysql_repl resource update mysql op stop interval=0 timeout=120s sudo pcs -f mysql_repl resource update mysql op monitor interval=20s timeout=30s sudo pcs -f mysql_repl resource update mysql op monitor interval=5s role=Master OCF_CHECK_LEVEL="1" sudo pcs -f mysql_repl resource update mysql op monitor interval=2s role=Slave OCF_CHECK_LEVEL="1" sudo pcs -f mysql_repl resource update mysql op promote interval=0 timeout=60s sudo pcs -f mysql_repl resource update mysql op demote interval=0 timeout=60s sudo pcs -f mysql_repl resource update mysql op notify interval=0 timeout=60s
Master-Slave セットを作成し、クラスターリソースを有効にします
sudo pcs -f mysql_repl resource promotable mysql mysql-clone master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 notify=true globally-unique="false" target-role="Master" is-managed="true" sudo pcs -f mysql_repl resource enable mysql-clone
制約の設定
IPアドレスと、MySQL の master は同じホストになるように制約を設定します。
sudo pcs -f mysql_repl constraint colocation add ClusterIP with Master mysql-clone INFINITY sudo pcs -f mysql_repl constraint order promote mysql-clone then start ClusterIP symmetrical=false score=INFINITY sudo pcs -f mysql_repl constraint order demote mysql-clone then stop ClusterIP symmetrical=false score=0
設定反映
sudo pcs cluster cib-push mysql_repl
host2をunstandby
sudo pcs node unstandby host2
状態表示
host1/host2がOnlineで、host1がPromoted, host2がUnpromotedになります。
vagrant@host1:~$ sudo pcs status Cluster name: ubuntu Cluster Summary: * Stack: corosync * Current DC: host1 (version 2.1.2-ada5c3b36e2) - partition with quorum * Last updated: Thu Jun 8 00:23:01 2023 * Last change: Thu Jun 8 00:17:20 2023 by root via cibadmin on host1 * 2 nodes configured * 3 resource instances configured Node List: * Online: [ host1 host2 ] Full List of Resources: * ClusterIP (ocf:heartbeat:IPaddr2): Started host1 * Clone Set: mysql-clone [mysql] (promotable): * Promoted: [ host1 ] * Unpromoted: [ host2 ] Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled
テスト
Host1 を standby にしてみます。
sudo pcs node standby host1
しばらく待つ(1,2分)と、host2にPrimaryが切り替わります。pcsの状態表示では、host2がPromotedになり、host1がStoppedになります。
vagrant@host1:~$ sudo pcs status Cluster name: ubuntu Cluster Summary: * Stack: corosync * Current DC: host2 (version 2.1.2-ada5c3b36e2) - partition with quorum * Last updated: Fri Jun 16 01:47:18 2023 * Last change: Fri Jun 16 01:47:03 2023 by root via crm_attribute on host2 * 2 nodes configured * 3 resource instances configured Node List: * Node host1: standby * Online: [ host2 ] Full List of Resources: * ClusterIP (ocf:heartbeat:IPaddr2): Started host2 * Clone Set: mysql-clone [mysql] (promotable): * Promoted: [ host2 ] * Stopped: [ host1 ] Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled
Master/Slaveの手動切り替え
host1をstandbyにするには、以下のコマンドを実行します。
sudo pcs node standby host1
しばらく(1、2分)すると、Master/Slaveが切り替わります。 host1はstopped状態になりますが、これは正常です。復活させるには、以下のコマンドを実行します。
sudo pcs node unstandby host1
こうすると、host1のMySQLが起動し、Slaveになります。
テスト書き込みスクリプト
切り替えテストでは、以下のスクリプト実行して書き込み状況を関すると分かりやすいです。
#!/bin/bash # MYSQLCRED='-u writeuser -pwrites -h 192.168.56.10' mysql $MYSQLCRED -e "create database if not exists test;" mysql $MYSQLCRED -e "create table if not exists writeload (id int not null auto_increment,data char(10), primary key (id)) engine = innodb;" test while [ 1 ] do mysql $MYSQLCRED -e "insert into writeload values (data) values ('test');" test sleep 1 done