MySQL Group Replication: 本番環境データベースの可用性を高める「救世主」

MySQL tutorial - IT technology blog
MySQL tutorial - IT technology blog

伝統的なMaster-Slave構成という「悪夢」

以前、ECサイトのMaster-Slave構成のMySQLクラスタでトラブルが発生し、一晩中対応したことがあります。ハードウェアの故障でMasterサーバーが突然ダウンしました。予備のSlaveはありましたが、データの差異を確認し、手動でSlaveをMasterに昇格させ、アプリケーション側のIPを更新するのに30分以上かかりました。1分間に数百件の注文を処理するシステムにとって、30分のダウンタイムは収益面で致命的な打撃となります。

旧来のレプリケーションにおける最大の課題は、その手動性にあります。トラブル発生時には直接的な介入が避けられず、また非同期通信であるためにデータ紛失(データロス)のリスクも常に付きまといます。MySQL Group Replication (GR) はこれらの不安を解消し、真の自己修復(Self-healing)機能を提供するために登場しました。

MySQL Group Replicationの仕組み

本質的に、Group ReplicationはMySQLサーバーを一つの統合されたグループとして連携させるプラグインです。データの一方向送信ではなく、グループ内の各ノードがPaxosコンセンサスプロトコルを通じて「合意」を形成します。

トランザクションは、グループ内の過半数のノードが同意したときにのみ成功と見なされます。この仕組みにより、以下の2つの核となる価値が提供されます:

  • 自動フェイルオーバー: ノードに障害が発生した場合、システムは10秒以内に新しいリーダーを自動的に選出します。深夜に飛び起きてコマンドを叩く必要はもうありません。
  • データの一貫性: クラッシュ時のゴーストデータやトランザクションの消失を排除します。1台でもノードが稼働していれば、データは安全に保たれます。

実際に200GBのデータベースを運用した際、ネットワークインフラが安定した同一リージョン内であれば、レイテンシの増加はごくわずaか(通常5ms未満)であることを確認できました。

実践に向けた環境準備

多数決による合意形成メカニズムを安定させるため、最低3つのノードが必要です。このガイドでは、以下のIPアドレスを持つMySQL 8.0が動作する3台のVPSを使用します:

  • ノード 1: 192.168.1.10 (mysql-1)
  • ノード 2: 192.168.1.11 (mysql-2)
  • ノード 3: 192.168.1.12 (mysql-3)

重要な注意点:Group Replicationでは、すべてのテーブルで InnoDB エンジンを使用し、かつ Primary Key(主キー) が必須です。主キーがない場合、一貫性を保護するためにGRによって書き込み操作が即座に拒否されます。

ステップ1:my.cnf設定ファイルの最適化

3つのノードすべてで、MySQLの設定ファイル(通常は /etc/mysql/mysql.conf.d/mysqld.cnf)を開きます。これがGroup Replicationを有効にするための骨組みとなります。

[mysqld]
# サーバー識別子 (ノード1は1、ノード2は2...)
server_id = 1 
binlog_format = ROW
log_slave_updates = ON
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE

# Group Replicationの設定
transaction_write_set_extraction = XXH64
loose-group_replication_group_name = "550e8400-e29b-41d4-a716-446655440000"
loose-group_replication_start_on_boot = OFF
loose-group_replication_local_address = "192.168.1.10:33061"
loose-group_replication_group_seeds = "192.168.1.10:33061,192.168.1.11:33061,192.168.1.12:33061"
loose-group_replication_bootstrap_group = OFF

# シングルプライマリモード (データ書き込みの安全性を確保)
loose-group_replication_single_primary_mode = ON
loose-group_replication_enforce_update_everywhere_checks = OFF

ポート 33061 のファイアウォールを必ず開放してください。これはノード同士が互いの稼働状況を確認するための専用通信チャネルです。

ステップ2:レプリケーション用ユーザーの設定

MySQLを再起動した後、同期を専門に担当する「郵便配達員」のようなユーザーを作成する必要があります。3つのノードすべてでMySQLにログインし、以下を実行します:

SET SQL_LOG_BIN=0;
CREATE USER 'repl'@'%' IDENTIFIED BY 'super_strong_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;

CHANGE REPLICATION SOURCE TO SOURCE_USER='repl', SOURCE_PASSWORD='super_strong_password' FOR CHANNEL 'group_replication_recovery';

ヒント:SET SQL_LOG_BIN=0 コマンドを使用することで、ユーザー作成がバイナリログに記録されないようにします。これにより、ノードが連携を開始する際のデータ競合を防ぐことができます。

ステップ3:グループの初期化(ブートストラップ)

以下のコマンドは、ノード1でのみ実行してください。これが新しいグループを「誕生」させる操作です。

INSTALL PLUGIN group_replication SONAME 'group_replication.so';

SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;

performance_schema.replication_group_members テーブルをクエリしてステータスを確認します。MEMBER_STATE カラムが ONLINE と表示されていれば、グループは正式に稼働しています。

ステップ4:残りのノードを接続する

ノード2とノード3の参加は非常に簡単です。以下のコマンドを実行するだけです:

INSTALL PLUGIN group_replication SONAME 'group_replication.so';
START GROUP_REPLICATION;

システムは自動的にノード1の既存データと照合します。差異がある場合、新しいノードは完全に同期されるまで自動的にデータをプルします。

運用における実践的なアドバイス

構築することと、安定して運用することは別物です。私が経験から学んだ3つの「血肉となる」注意点を挙げます:

  1. ネットワーク遅延: GRはネットワークのレイテンシに非常に敏感です。ノード間のPingが100msを超えると、システムがノードのダウンと誤認し、グループから頻繁に除外される可能性があります。
  2. ProxySQLの併用: アプリケーションをMySQLのIPに直接接続させないでください。ProxySQLを使用して、読み取り/書き込みトラフィックを自動的に振り分けます。Masterがダウンしても、ProxySQLはミリ秒単位で新しいMasterを認識します。
  3. バイナリログの制限: 継続的な同期により、バイナリログファイルは急速に肥大化します。ディスク容量の突然の枯渇を防ぐため、binlog_expire_logs_seconds を3〜7日程度に設定することをお勧めします。

Lời kết

MySQL Group Replicationは単なる技術ではなく、運用チームに「安心」をもたらすものです。初期設定はMaster-Slaveよりも手間がかかりますが、自己修復能力とデータ保護のメリットは、その労力に見合う十分な価値があります。99.99%の可用性が求められるシステムを管理しているなら、今すぐGRの検証を始めてみてください。

Share: