MariaDB のクラスターとして使われる Galera Cluster で、既にクラスターとして稼働しており、無停止で新規ノードの追加を行う場合の運用寄りの手順を紹介します。
Galera Cluster の初期構築方法については検索すると沢山参考になるサイトがあるのですが、Galera Cluster の運用において新規ノードを追加させる手順があまり載っていませんでしたのでそのノウハウを書きます。
サーバ構成
- MariaDB(mysql Ver 15.1 Distrib 10.3.36-MariaDB, for Linux) インストール済みの既存DBサーバ(CentOS7) × 3台
- MariaDB(同上) インストール済みの新規DBサーバ(CentOS7) × 1台
概要
すでに既存のDBサーバが3台で稼働していて、新規DBサーバを構築し既存DBサーバのデータをリストア後に Galera Cluster の新規ノードとして追加させます。
そしてレプリケーションが行われ、計4台としてデータの同期が行われる状態にします。
作業の流れ
何も考えずに新規のDBサーバで MariaDB(Galera Cluster設定ありで) ノードを起動すると、SST(State Snapshot Transfer)により既存のDBサーバ(ドナーノード)の更新が長時間ロックされてしまうことから、下記の流れで作業を実施します。
- 既存DBサーバのどれか1台からmysqldumpを実行
- 取得したdumpファイルを新規DBサーバに転送し、リストア実施 ※この段階では新規DBサーバはクラスターに参加していない(単独で動作)
- 新規DBサーバのクラスター設定を変更し、データを完全同期 ※この段階でGalera Clusterからは計4台として同期
新規DBサーバはdumpファイルからリストアし、そのあと適切にGalera Cluster設定を変更した後にクラスター参加を行うことでDBサイズが巨大である場合でもレプリケーションに時間をあまり要することなくかつ安全にクラスターを組むことができます。
既存のDBサーバからmysqldumpを取得
既存のDBサーバでgzip圧縮を行いつつmysqldumpを実行、そのまま新規DBサーバにdumpファイルを転送します。
※single-transaction オプションにより、mysqldump実行中でもロックは行われないようにします
$ mysqldump -u root --all-databases --single-transaction --routines --master-data=2 --flush-logs | gzip | ssh -A {新規DBサーバ名} 'cat > ~/yyyymmdd-dump.sql.gz'
新規DBサーバでリストア
新規DBサーバには予めMariaDBがインストールされていることを前提として、リストア作業を行います。
リストア・レプリケーション作業
/etc/my.cnf.d/server.cnf
の設定ファイルからGalera Cluster関連の設定が存在する場合は一通り削除 or コメントアウト- MariaDB サービス起動
sudo systemctl start mariadb
- サービス起動確認
systemctl status mariadb
- (正しくサービスが起動されていたら)リストア実行 ※pv(pipeviewer)でプログレスバー表示
pv yyyymmdd-dump.sql.gz | zcat | mysql -u root
/etc/my.cnf.d/server.cnf
を編集しGalera Clusterの設定を有効状態にする
差分データの転送中にドナーノードがREAD ONLYになってしまうため、wsrep_sst_donor
の値を設定しREAD ONLYになっても良いノード名を指定します下記は設定例です
[galera] wsrep_on=ON wsrep_provider=/usr/lib64/galera/libgalera_smm.so wsrep_cluster_name="DBCLUSTER" # wsrep_cluster_address ・・・ 全てのノードのIPアドレスを指定 wsrep_cluster_address = gcomm:// wsrep_node_name='db_4' # wsrep_node_address ・・・ 自サーバのIPアドレスを入力 wsrep_node_address= wsrep_sst_method=rsync wsrep_sst_donor_rejects_queries=ON # wsrep_slave_threads ・・・ CPUコア数の2倍もしくはクライアント接続数の1/4の目安値 wsrep_slave_threads=4 innodb_autoinc_lock_mode=2 wsrep_auto_increment_control=OFF auto_increment_increment=1 # wsrep_sst_donor ・・・ ドナーとして使用するノード名(wsrep_node_name)を指定 参考:https://galeracluster.com/library/documentation/mysql-wsrep-options.html#wsrep-sst-donor wsrep_sst_donor=
- MariaDB サービス再起動
このタイミングでレプリケーションが行われるので、起動に時間が掛かります
sudo systemctl restart mariadb
リストアに失敗した場合
4.のリストア作業で何らかの原因で失敗した場合、下記の方法でMariaDBの初期化を行った後作業に戻ります。
// mysqlファイルを削除
$ cd /var/lib/mysql/
$ sudo rm -rf *
// 初期化実施
$ sudo mysqld --initalize-insecure --user=mysql
// システムテーブルの作成 ※これを実行しないとサービス起動に失敗します
$ sudo mysql_install_db --datadir=/var/lib/mysql --user=mysql
// サービス起動
$ sudo systemctl start mariadb
Galera Cluster 確認
リストア・レプリケーション作業が終わったら、Galera Clusterが全てのノードを認識しているかチェックします。
$ sudo mysql
MariaDB [(none)]> show status where Variable_name = 'wsrep_local_state_comment' or Variable_name = 'wsrep_cluster_status' or Variable_name = 'wsrep_incoming_addresses' or Variable_name = 'wsrep_cluster_size' or Variable_name = 'wsrep_last_committed' or Variable_name = 'wsrep_ready';
+---------------------------+-----------------------------------------------------------------------------+
| Variable_name | Value |
+---------------------------+-----------------------------------------------------------------------------+
| wsrep_cluster_size | 4 |
| wsrep_cluster_status | Primary |
| wsrep_incoming_addresses | 172.17.x.1:3306,172.17.x.2:3306,172.17.x.3:3306,172.17.x.4:3306 |
| wsrep_last_committed | 123068 |
| wsrep_local_state_comment | Synced |
| wsrep_ready | ON |
+---------------------------+-----------------------------------------------------------------------------+
6 rows in set (0.002 sec)
以上で新規ノードを追加を行い、計4台のクラスターとして構成させることができました。
ただしGalera Clusterは奇数ノードの構成を推奨しており、偶数の場合スプリットブレインのリスクが高まるため
Galera Arbitratorを使い、疑似ノードをさらに1つ追加させ計5台として構成させる方法について後日記載致します。
Galera Arbitratorを用いたスプリットブレイン対策について記事を更新しました↓
ピンバック: Galera Arbitratorを使いGalera Clusterのスプリットブレイン対策を行う | Gadgetter ガジェッター