すべてのプロダクト
Search
ドキュメントセンター

Elastic Compute Service:MySQL InnoDB Cluster 高可用性の実践

最終更新日:May 30, 2025

単一の MySQL データベースサーバーにはパフォーマンスの制限があり、単一障害点(SOPF)のリスクがあります。これは、業務システムの可用性を損なう可能性があります。複数の Elastic Compute Service(ECS)インスタンスを使用して高可用性 MySQL InnoDB Cluster を構築し、プロキシサービスを使用して柔軟なスケジューリングと読み書き分離を実現することで、データベースの可用性と耐障害性を向上させることができます。

アーキテクチャ

サービス クラスタを構築する場合、複数ゾーンにまたがる ECS インスタンスを使用すると、ビジネスのダウンタイムのリスクが軽減され、単一ゾーン障害に対する回復力が提供され、業務システムの安定性が向上します。

  • プロキシノード:クライアントリクエストを処理し、適切なデータベースノードに転送する役割を担います。プロキシノードは複数ゾーンにデプロイして、高可用性をさらに強化できます。

  • プライマリノード:クラスタのコアデータ処理ノードとして機能し、すべての書き込み操作を処理し、他のノードにデータを同期します。

  • セカンダリノード:プライマリノードからデータをレプリケートすることでデータ整合性を維持し、読み取り操作のみをサポートします。プライマリノードに障害が発生した場合、セカンダリノードから新しいプライマリノードが自動的に選出され、クラスタの継続的な動作が保証されます。

image

環境を準備する

  1. 4 つの ECS インスタンスを作成します。この例では、Alibaba Cloud Linux 3 を実行する ECS インスタンスが作成されます。

    説明

    インスタンス

    インターネットアクセス

    仮想プライベートクラウド (VPC)

    vSwitch

    IP アドレス

    プロキシノード

    ECS インスタンス A

    インターネットアクセスが必要です。

    MySQL をインストールした後、セキュリティを強化するためにインターネットアクセスを無効にします。

    192.168.0.0/16

    192.168.0.0/24

    192.168.0.1

    プライマリノード (読み書き)

    ECS インスタンス B

    192.168.1.0/24

    192.168.1.1

    セカンダリノード (読み取り専用)

    ECS インスタンス C

    192.168.2.0/24

    192.168.2.1

    セカンダリノード (読み取り専用)

    ECS インスタンス D

    192.168.2.2

  2. ECS インスタンス B、C、および D に同じ MySQL バージョンをインストールします。この例では、MySQL 8.4 がインストールされています。 MySQL のインストール方法については、「Linux ECS インスタンスに MySQL データベースをデプロイする」をご参照ください。

手順

ステップ 1:クラスタノードを構成する

  1. ECS インスタンス B、C、および D に接続します。詳細については、「Workbench を使用して SSH 経由で Linux インスタンスに接続する」をご参照ください。

  2. ECS インスタンス B、C、および D に、同じユーザー名とパスワードを持つ同じ MySQL アカウントを作成します。

    重要
    • <username> は、作成する MySQL アカウントのユーザー名に置き換えます。

    • <password> は MySQL アカウントのパスワードに置き換えます。パスワードは 8 文字以上で、大文字、小文字、数字、特殊文字をそれぞれ 1 つ以上含める必要があります。

    #次のコマンドを実行した後、ルートユーザーのパスワードを入力します。
    sudo mysql -uroot -p \
    -e "CREATE USER '<username>'@'%' IDENTIFIED BY '<password>';" \
    -e "GRANT ALL PRIVILEGES ON *.* TO '<username>'@'%' WITH GRANT OPTION;" \
    -e "FLUSH PRIVILEGES;"
  3. ECS インスタンス B、C、および D の /etc/my.cnf MySQL 構成ファイルに次の内容を追加します。

    #ホスト名をノードの IP アドレスに設定します。
    report_host=192.168.x.x
    #GTID 強整合性を有効にします。
    enforce_gtid_consistency=ON
    gtid_mode=ON
    #ノードサービス ID を指定します。これは、各ノードに対して一意の正の整数である必要があります。
    server_id=1
    #各ノードの最大接続数を指定します。これは、すべてのノードで同じである必要があります。
    max_connections=1024
    #InnoDB 以外のストレージエンジンを無効にします。
    disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
  4. 構成の変更を有効にするために、ECS インスタンス B、C、および D で MySQL サービスを再起動します。

    sudo systemctl restart mysqld

ステップ 2:クラスタを作成する

  1. ECS インスタンス A に接続します。詳細については、「Workbench を使用して SSH 経由で Linux インスタンスに接続する」をご参照ください。

  2. ECS インスタンス A に mysql-shell と mysql-router をインストールします。

    #公式 MySQL リポジトリを追加します。
    sudo rpm -Uvh https://repo.mysql.com/mysql84-community-release-el8-1.noarch.rpm
    #mysql-shell と mysql-router をインストールします。
    sudo dnf install -y mysql-shell mysql-router mysql-community-client
  3. MySQL Shell を使用してプライマリノードに接続します。<username> は、「手順 1:クラスタノードを構成する」で作成した MySQL アカウントのユーザー名に置き換え、<IP> はプライマリノードの IP アドレスに置き換えます。 MySQL アカウントのパスワードを入力し、プロンプトに従ってパスワードを保存するかどうかを選択します。パスワードを保存すると、後続の接続でパスワードを入力する必要がなくなります。

    mysqlsh --js <username>@<IP>:3306

    image

  4. クラスタを作成します。 <cluster_name> はクラスタ名に置き換えます。<cluster_name>

    var cluster = dba.createCluster('<cluster_name>');
  5. セカンダリノードをクラスターに追加します。<username> は、「ステップ 1: クラスターノードを構成する」で作成した MySQL アカウントのユーザー名に置き換え、<IP> はセカンダリノードの IP アドレスに置き換えます。すべてのセカンダリノードを追加するには、このステップを繰り返します。

    説明

    たとえば、IP アドレス 192.168.2.1 とユーザー名 cluster_user を持つノードを追加するには、cluster.addInstance('cluster_user@192.168.2.1:3306'); コマンドを実行します。

    cluster.addInstance('<username>@<IP>:3306');

    次の出力は、セカンダリノードが追加されたことを示しています。image

  6. クラスタの状態を確認します。

    cluster.status();

    次の出力は、クラスタが作成されたことを示しています。image

ステップ 3:プロキシノードを構成する

  1. ECS インスタンス A に接続します。詳細については、「Workbench を使用して SSH 経由で Linux インスタンスに接続する」をご参照ください。

  2. プロキシ設定を初期化します。<username> は、「手順 1:クラスタノードを構成する」で作成した MySQL アカウントのユーザー名に置き換え、<IP> はプライマリノードの IP アドレスに置き換えます。プロンプトが表示されたら、MySQL アカウントのパスワードを入力します。

    説明

    デフォルトでは、コマンドは初期化ファイルを /mnt/mysqlrouter ディレクトリに保存します。

    sudo mysqlrouter --bootstrap <username>@<IP>:3306 --directory /mnt/mysqlrouter \
    --conf-bind-address 0.0.0.0 --user=mysqlrouter
  3. mysqlrouter サービスファイルを編集します。

    説明

    デフォルトでは、コマンドは /mnt/mysqlrouter ディレクトリを使用します。ディレクトリを変更した場合は、ExecStart パスと ExecStop パスを更新する必要があります。

    sudo tee /usr/lib/systemd/system/mysqlrouter.service <<-'EOF'
    [Unit]
    Description=MySQL Router Service
    After=network.target
    
    [Service]
    User=mysqlrouter
    Group=mysqlrouter
    Type=forking
    ExecStart=/mnt/mysqlrouter/start.sh
    ExecStop=/mnt/mysqlrouter/stop.sh
    Restart=on-failure
    StandardOutput=journal
    
    [Install]
    WantedBy=multi-user.target
    EOF
  4. mysqlrouter サービスを開始します。

    #サービスファイルを更新します。
    sudo systemctl daemon-reload
    #mysqlrouter サービスを開始します。
    sudo systemctl start mysqlrouter.service
    #mysqlrouter が起動時に自動的に開始されるように構成します。
    sudo systemctl enable mysqlrouter.service
    #mysqlrouter サービスの状態を確認します。
    sudo systemctl status mysqlrouter.service

クラスタを検証する

プライマリノード(ECS インスタンス B)を停止して障害をシミュレートし、クラスタが自動的にノードを切り替えてサービスを提供し続けることを検証します。

  1. ECS インスタンス A に接続します。詳細については、「Workbench を使用して SSH 経由で Linux インスタンスに接続する」をご参照ください。

  2. MySQL クライアントを使用して、プロキシノード(ECS インスタンス A)に接続します。<username> は、「手順 1:クラスタノードを構成する」で作成した MySQL アカウントのユーザー名に置き換えます。

    mysql -h127.0.0.1 -P6450 -u<username> -p
  3. 次の SQL 文を実行して、クラスタの状態を確認します。結果は、3 つのノードがオンラインで、1 つのノードがプライマリノードとして機能していることを示しています。

    SELECT * FROM performance_schema.replication_group_members;

    image

  4. SQL 文を実行して、テストデータベースとテストテーブルを追加します。

    -- 1. データベースを作成します。
    CREATE DATABASE test_db;
    
    -- 2. データベースを使用します。
    USE test_db;
    
    -- 3. test_table という名前のテーブルを作成します。
    CREATE TABLE test_table (
        id INT AUTO_INCREMENT PRIMARY KEY, -- 自動インクリメント プライマリキー
        name VARCHAR(100) NOT NULL,        -- 名前
        value DECIMAL(10, 2) NOT NULL
    );
    
    -- 4. test_table にエントリを追加します。
    INSERT INTO test_table (name, value) VALUES
    ('Item A', 100.50),
    ('Item B', 200.75);
  5. プライマリノード(ECS インスタンス B)を停止して、故障イベントをシミュレートします。

  6. プライマリノードが停止した後、次の SQL 文を再度実行して、クラスタの状態を確認します。 2 つのノードがオンラインで、セカンダリノードがプライマリノードになっていることがわかります。

    SELECT * FROM performance_schema.replication_group_members;

    image

  7. 次の SQL 文を実行してデータをクエリし、データ損失を確認します。

    SELECT * FROM test_table;
  8. プライマリノード(ECS インスタンス B)を起動して、故障からの回復をシミュレートします。

  9. 次の SQL 文を実行して、クラスタの状態を確認します。結果は、3 つのノードがオンラインで、ECS インスタンス B が自動的にクラスタに参加していることを示しています。

    SELECT * FROM performance_schema.replication_group_members;

    image

クラスタにノードを追加する

MySQL InnoDB Cluster をスケールアップする場合、またはクラスタ内のノードに障害が発生した場合は、MySQL Shell を使用してクラスタに接続し、 addInstance コマンドを実行して新しいノードを追加します。新しいノードは自動的にデータを同期します。addInstance を追加

重要
  • クラスタ内のノードの半分以上が故障すると、クラスタは使用できなくなります。可用性を確保するために、クラスタ内のノード数を奇数に構成することをお勧めします。

  • ノードがクラスタに参加する前に、ノードに MySQL をインストールし、ステップ 1:クラスタノードを構成する の手順 2、3、および 4 を実行して構成します。

  1. ECS インスタンス A に接続します。詳細については、「Workbench を使用して SSH 経由で Linux インスタンスに接続する」をご参照ください。

  2. MySQL Shell を使用して、クラスタ内の任意のノードに接続します。 <username> は、<username>ステップ 1:クラスタノードを構成する で作成した MySQL アカウントのユーザー名に置き換え、<IP> はノードの IP アドレスに置き換えます。 MySQL アカウントのパスワードを入力し、プロンプトが表示されたらパスワードを保存するかどうかを選択します。パスワードを保存すると、後続の接続でパスワードを入力する必要がなくなります。<IP>

    mysqlsh --js <username>@<IP>:3306
  3. クラスタ情報を取得します。

    var cluster = dba.getCluster();
  4. クラスタにノードを追加します。<username> は、「手順 1: クラスタノードを構成する」で作成した MySQL アカウントのユーザー名に置き換え、<IP> はノードの IP アドレスに置き換えます。

    説明

    たとえば、IP アドレス 192.168.2.1 とユーザー名 cluster_user を使用してノードを追加するには、cluster.addInstance('cluster_user@192.168.2.1:3306'); コマンドを実行します。

    cluster.addInstance('<username>@<IP>:3306');

    次の出力は、ノードが追加されたことを示しています。image

クラスタのプライマリノードを指定する

MySQL InnoDB Cluster では、プライマリノードに障害が発生した場合、残りのノードから新しいプライマリノードが自動的に選出されます。 MySQL Shell を使用してクラスターに接続し、setPrimaryInstance コマンドを実行して、プライマリノードを手動で指定できます。

  1. ECS インスタンス A に接続します。詳細については、「Workbench を使用して SSH 経由で Linux インスタンスに接続する」をご参照ください。

  2. MySQL Shell を使用して、クラスタ内の任意のノードに接続します。<username> は、「手順 1: クラスタノードを構成する」で作成した MySQL アカウントのユーザー名に置き換え、<IP> はノードの IP アドレスに置き換えます。 MySQL アカウントのパスワードを入力し、プロンプトが表示されたらパスワードを保存するかどうかを選択します。パスワードを保存すると、後続の接続でパスワードを入力する必要がなくなります。

    mysqlsh --js <username>@<IP>:3306
  3. クラスタ情報を取得します。

    var cluster = dba.getCluster();
  4. クラスターのプライマリノードを指定します。<username> は、「手順 1: クラスタノードを構成する」で作成した MySQL アカウントのユーザー名に置き換え、<IP> はノードの IP アドレスに置き換えます。

    説明

    たとえば、IP アドレス 192.168.2.1 とユーザー名 cluster_user を持つノードをプライマリノードとして指定するには、 cluster.setPrimaryInstance('cluster_user@192.168.2.1:3306'); コマンドを実行します。

    cluster.setPrimaryInstance('<username>@<IP>:3306');

    次の出力は、ノードがプライマリノードとして構成されたことを示しています。image

参考文献

  • MySQL InnoDB Cluster については、MySQL 公式ドキュメントをご参照ください。

  • デプロイと管理を簡素化するために、ApsaraDB RDS を使用することをお勧めします。詳細については、「ApsaraDB RDS for MySQL とは」をご参照ください。

  • CPU、メモリ、ディスク I/O、ネットワークトラフィックなどのメトリックを含め、クラスタサービスをリアルタイムで監視して、例外を迅速に検出して処理します。詳細については、「CloudMonitor とは」をご参照ください。