Percona XtraDB Cluster (PXC) の概要
Percona XtraDB Cluster(PXC)は、GaleraライブラリをベースとしたMySQLの同期マルチマスタレプリケーションソリューションです。従来の非同期レプリケーションと比較し、PXCはデータの整合性を厳密に保証し、レプリケーション遅延を事実上排除することでリアルタイムに近いデータ同期を実現します。クラスタ内のすべてのノードは対等な関係(マルチマスタ)にあり、どのノードに対しても読み書き操作が可能です。これにより、金融取引やECサイトなど、データの整合性が最優先されるシステムにおいて高い信頼性を提供します。
PXCの主な長所と短所
- 長所:
- サービスの高可用性:単一障害点(SPOF)が存在しない。
- 同期レプリケーション:データが全ノードに即座に反映され、遅延が最小限。
- スケーラビリティ:複数ノードでの並列書き込みが可能(ただし競合回避には設計が必要)。
- 自動構成:新規ノードの追加が容易で、自動的にデータが同期される。
- 厳密な整合性:トランザクションは全ノードでコミットされるか、全てロールバックされる。
- 短所:
- ストレージエンジンの制限:InnoDBのみがサポートされる。
- 書き込み性能のボトルネック:最も処理が遅いノードに全体の速度が合わせられる。
- 要件:全テーブルに主キーが必要。
- 制限事項:LOCK TABLESなどの明示的なロック操作はサポートされない。
- 競合のリスク:多重度の高い書き込みによりデッドロックや競合が発生しやすくなる可能性がある。
従来のレプリケーションとの違い
| 項目 | 従来のMySQLレプリケーション | PXC (Galera) |
|---|---|---|
| 通信方向 | MasterからSlaveへの一方通行。 | 全ノード間で双方向通信。 |
| 同期方式 | 非同期。MasterとSlaveでデータの不整合が起こり得る。 | 同期。全ノードで同時にトランザクションをコミットする。 |
| 接続先 | 書き込みはMasterのみ。 | どのノードでも読み書きが可能。 |
主要ポート: データ通信 (3306)、SST全量転送 (4444)、グループ通信 (4567)、IST増分転送 (4568) を使用します。
PXCクラスタの構築手順
ここでは、Rocky Linux 8環境をベースに、3ノード構成のPXCクラスタを構築します。ノード間で時刻同期(NTP等)がされている前提とします。
1. 環境準備とインストール
以下の3台のサーバーを用意し、ホスト名解決を設定します。
| ホスト名 | IPアドレス | 役割 |
|---|---|---|
| db-node-01 | 10.0.0.10 | Node 1 |
| db-node-02 | 10.0.0.11 | Node 2 |
| db-node-03 | 10.0.0.12 | Node 3 |
# 全ノードで /etc/hosts を編集
10.0.0.10 db-node-01
10.0.0.11 db-node-02
10.0.0.12 db-node-03
# リポジトリの設定とPXCのインストール
dnf module disable mysql -y
dnf install https://repo.percona.com/yum/percona-release-latest.noarch.rpm -y
percona-release setup pxc-80
dnf install percona-xtradb-cluster -y
2. データベースの初期設定
まずは単体のMySQLとして基本的な設定を行い、rootパスワードを変更します。設定ファイル `/etc/my.cnf` を編集し、サーバーIDを一意にします。
[mysqld]
server-id=1001
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
binlog_expire_logs_seconds=604800
サービスを起動し、一時パスワードを確認して変更します。
systemctl start mysql
# ログからパスワードを抽出
grep 'temporary password' /var/log/mysqld.log
# パスワード変更
mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'SecurePass123!';
exit;
3. クラスタ設定の適用
全ノードのMySQLサービスを停止し、PXC用の設定を `/etc/my.cnf` に追加します。各ノードで `wsrep_node_address` と `wsrep_node_name` はそれぞれの環境に合わせて変更してください。
systemctl stop mysql
# /etc/my.cnf への追記例 (db-node-01の場合)
[mysqld]
# Galeraライブラリの指定
wsrep_provider=/usr/lib64/galera4/libgalera_smm.so
# クラスタ構成メンバーのアドレスリスト
wsrep_cluster_address=gcomm://10.0.0.10,10.0.0.11,10.0.0.12
# クラスタ名
wsrep_cluster_name=production_ha_cluster
# 自ノードの識別情報
wsrep_node_name=db-node-01
wsrep_node_address=10.0.0.10
# 同期レプリケーション必須設定
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
# スレッドと競合ログ
wsrep_slave_threads=4
wsrep_log_conflicts=1
# 厳格モードとSST方式
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
SSL/TLS通信設定により、ノード間のトラフィックはデフォルトで暗号化されます。最初のノード(起動元)で生成されたSSL証明書(`*.pem`)を他のノードのデータディレクトリへコピーし、権限を設定する必要があります。
# db-node-01 で実行
cd /var/lib/mysql
scp *.pem root@db-node-02:/var/lib/mysql/
scp *.pem root@db-node-03:/var/lib/mysql/
# 各ターゲットノードで権限修正
chown mysql:mysql /var/lib/mysql/*.pem
4. クラスタの起動
最初のノードのみ「ブートストラップモード」で起動し、新しいクラスタを生成します。その後、他のノードを通常起動してクラスタに参加させます。
# 最初のノード (db-node-01) のみ
systemctl start mysql@bootstrap.service
# 2台目以降のノード (db-node-02, db-node-03)
systemctl start mysql
5. 動作確認
クラスタの状態を確認し、全ノードが正常に参加しているか検証します。
mysql> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
mysql> SHOW STATUS LIKE 'wsrep_cluster_status';
+----------------------+---------+
| Variable_name | Value |
+----------------------+---------+
| wsrep_cluster_status | Primary |
+----------------------+---------+
mysql> SELECT * FROM performance_schema.pxc_cluster_view\G
*************************** 1. row ***************************
HOST_NAME: db-node-01
UUID: 3d1a3c22-8f12-11ee-9b6a-08002734ed5a
STATUS: Synced
LOCAL_INDEX: 0
SEGMENT: 0
...
ノードの運用管理
PXCクラスタはノードの動的な追加・削除をサポートしていますが、サービスの停止方法は起動方法と対応させる必要があります。
- ブートストラップモード (`mysql@bootstrap`) で起動したノードを停止する場合:
systemctl stop mysql@bootstrap.service - 通常モードで起動したノードを停止する場合:
systemctl stop mysql