Ubuntu20.04でMySQLグループレプリケーションを構成する方法

提供:Dev Guides
移動先:案内検索

序章

MySQLレプリケーションは、あるデータベースから別のデータベースにデータと操作を確実にミラーリングします。 従来のレプリケーションには、プライマリサーバーのログから独自のデータセットにアクションをコピーして適用するセカンダリサーバーとのデータベース書き込み操作を受け入れるように構成されたプライマリサーバーが含まれます。 これらのセカンダリサーバーは読み取りに使用できますが、通常はデータ書き込みを実行できません。

グループレプリケーションは、より柔軟でフォールトトレラントなレプリケーションメカニズムを実装する方法です。 このプロセスには、データが正しくコピーされるようにするためにそれぞれが関与するサーバーのプールを確立することが含まれます。 プライマリサーバーで問題が発生した場合、メンバーの選出により、グループから新しいプライマリを選択できます。 これにより、問題が発生した場合でも、残りのノードが動作を継続できます。 メンバーシップネゴシエーション、障害検出、およびメッセージ配信は、Paxosコンセンサスアルゴリズムの実装を通じて提供されます。

このチュートリアルでは、3台のUbuntu20.04サーバーのセットを使用してMySQLグループレプリケーションを設定します。 MySQLにグループレプリケーションをデプロイするために必要なMySQLインスタンスの最小数は3であり、最大数は9であることに注意してください。 このチュートリアルを実行すると、グループをシングルプライマリまたはマルチプライマリレプリケーショングループとして設定するオプションが表示されます。

:データベースサーバーは、レプリケーションセットアップで2つの役割のいずれかを持つことができます。データベースサーバーは、プライマリインスタンスソースインスタンスとも呼ばれます)のいずれかです。ユーザーはデータを書き込むことができます。 またはreplica(またはセカンダリインスタンス)。これは、ソース上のすべてのデータのコピーを格納します。 歴史的に、これらの役割は、代わりにそれぞれマスターインスタンスおよびスレーブインスタンスと呼ばれてきました。 2020年7月に公開されたブログ投稿で、MySQLチームはこの用語の否定的な起源を認め、データベースプログラムとそのドキュメントをより包括的な言語を使用するように更新する取り組みを発表しました。

ただし、これは継続的なプロセスです。 MySQLのドキュメントとプログラムのバージョン8のコマンドの多くは更新されており、代わりにレプリケーショントポロジ内のサーバーをプライマリとそのセカンダリ(または ]sourceとそのreplicas)、否定的な用語がまだ表示されている場所があります。 このガイドでは、可能な限り、より包括的な用語がデフォルトで使用されますが、やむを得ず古い用語が使用される場合がいくつかあります。


前提条件

このガイドを完了するには、次のものが必要です。

  • Ubuntu20.04を実行している3台のサーバー。 それぞれに、sudo権限を持つ非ルート管理ユーザーと、UFWで構成されたファイアウォールが必要です。 Ubuntu 20.04 初期サーバーセットアップガイドに従って、各サーバーをセットアップします。
  • MySQLが各サーバーにインストールされています。 このガイドは、デフォルトのUbuntuリポジトリから入手できる最新バージョンのMySQLを使用していることを前提としています。これは、この記事の執筆時点ではバージョン8.0.28です。 これをすべてのサーバーにインストールするには、各マシンの Ubuntu20.04にMySQLをインストールする方法に関するガイドに従ってください。

わかりやすくするために、このガイドでは3つのサーバーを member1member2 、およびmember3と呼びます。 このガイド全体の例では、これらのメンバーは次のIPアドレスを持っています。

メンバー IPアドレス
member1 203.0.113.1
member2 203.0.113.2
member3 203.0.113.3

member1 で実行する必要のあるコマンドは、次のように背景が青色になります。


同様に、member2で実行する必要のあるコマンドはすべて赤い背景になります。


また、member3で実行する必要のあるコマンドはすべて緑色の背景になります。


最後に、3台のサーバーのそれぞれで実行する必要のあるコマンドには標準のバックグラウンドがあります。


ステップ1—MySQLグループを識別するためのUUIDの生成

MySQL構成ファイルを開いてグループ複製設定を構成する前に、作成するMySQLグループを識別するために使用できるUUIDを生成する必要があります。

member1 で、uuidgenコマンドを使用して、グループの有効なUUIDを生成します。

uuidgen
Output168dcb64-7cce-473a-b338-6501f305e561

サーバーのプールのグループ名を構成するときにすぐにこれを参照する必要があるため、受け取った値をコピーします。

ステップ2—MySQL構成ファイルでグループレプリケーションを設定する

これで、MySQLの構成ファイルを変更する準備が整いました。 好みのテキストエディタを使用して、各MySQLサーバーでメインのMySQL構成ファイルを開きます。 ここでは、nanoを使用します。

sudo nano /etc/mysql/my.cnf

Ubuntuでは、MySQLには、さまざまな構成変更を定義するために使用できるさまざまなファイルがインストールされています。 デフォルトでは、my.cnfファイルは、サブディレクトリから追加のファイルを調達するためにのみ使用されます。 !includedir行に独自の構成を追加する必要があります。 これにより、含まれているファイルの設定を上書きできます。

まず、[mysqld]ヘッダーを含めて新しいセクションを開始し、次の例で強調表示されているように、グループレプリケーションを有効にするために必要な設定を追加します。 これらの設定は、公式MySQLドキュメントで概説されているグループレプリケーションに必要な最小設定から変更されていることに注意してください。 loose-プレフィックスを使用すると、MySQLは、正常に認識されないオプションを失敗することなく処理できます。 これらの設定のいくつかをまもなく入力してカスタマイズする必要があります

/etc/mysql/my.cnf

. . .
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

[mysqld]

# General replication settings
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
log_bin = binlog
binlog_format = ROW
transaction_write_set_extraction = XXHASH64
loose-group_replication_bootstrap_group = OFF
loose-group_replication_start_on_boot = OFF
loose-group_replication_ssl_mode = REQUIRED
loose-group_replication_recovery_use_ssl = 1

# Shared replication group configuration
loose-group_replication_group_name = ""
loose-group_replication_ip_whitelist = ""
loose-group_replication_group_seeds = ""

# Single or Multi-primary mode? Uncomment these two lines
# for multi-primary mode, where any host can accept writes
#loose-group_replication_single_primary_mode = OFF
#loose-group_replication_enforce_update_everywhere_checks = ON

# Host specific replication configuration
server_id = 
bind-address = ""
report_host = ""
loose-group_replication_local_address = ""

これらの構成オプションのすべてをより明確に説明するために、これらは次のサブセクションに分割されています。 一部のセクションでは、レプリケーショングループを展開する方法についての選択肢が示されているか、独自の構成に固有の詳細を入力する必要があるため、これらを注意深くお読みください。

ボイラープレートグループの複製設定

最初のセクションには、変更を必要としないグループレプリケーションに必要な一般的な設定が含まれています。

/etc/mysql/my.cnf

. . .
# General replication settings
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
log_bin = binlog
binlog_format = ROW
transaction_write_set_extraction = XXHASH64
loose-group_replication_bootstrap_group = OFF
loose-group_replication_start_on_boot = OFF
loose-group_replication_ssl_mode = REQUIRED
loose-group_replication_recovery_use_ssl = 1
. . .

MySQLでのグループレプリケーションの特定の要件の1つは、データをInnoDBストレージエンジンに保存する必要があることです。 MySQLのドキュメントでは、このセクションの最初のコメントされていない行のような方法でエラーを引き起こす可能性のある他のストレージエンジンの使用を明示的に無効にすることを推奨しています。

残りの設定では、グローバルトランザクションIDをオンにし、グループレプリケーションに必要なバイナリログを構成し、グループのSSLを構成します。 この構成では、リカバリとブートストラップに役立つ他のいくつかの項目も設定されます。 このセクションでは何も変更する必要はありません。3つのサーバーすべてで同一である必要があるため、追加した後で先に進むことができます。

共有グループレプリケーション設定

2番目のセクションでは、グループの共有設定を設定します。 これを一度カスタマイズしてから、各ノードで同じ設定を使用する必要があります。 具体的には、グループのUUID(前の手順で作成したもの)、許可されたグループメンバーのリスト、およびグループに参加するときに初期データを取得するために連絡するシードメンバーを追加する必要があります。

loose-group_replication_group_nameを、uuidgenコマンドで以前に生成したUUID値に設定します。 UUIDは、空の二重引用符のペアの間に配置してください。

次に、loose-group_replication_ip_whitelistをすべてのMySQLサーバーのIPアドレスのリストにコンマで区切って設定します。 loose-group_replication_group_seeds設定はホワイトリストとほぼ同じである必要がありますが、指定されたグループレプリケーションポートを各メンバーの最後に追加する必要があります。 このガイドでは、推奨されるグループレプリケーションポート33061を使用します。

/etc/mysql/my.cnf

. . .
# Shared replication group configuration
loose-group_replication_group_name = "168dcb64-7cce-473a-b338-6501f305e561"
loose-group_replication_ip_whitelist = "203.0.113.1,203.0.113.2,203.0.113.3"
loose-group_replication_group_seeds = ""203.0.113.1:33061,203.0.113.2:33061,203.0.113.3:33061"
. . .

このセクションは、各MySQLサーバーで同じである必要があるため、それぞれに注意深くコピーしてください。

シングルプライマリまたはマルチプライマリの選択

次に、シングルプライマリまたはマルチプライマリグループのどちらを構成するかを決定する必要があります。 シングルプライマリ構成では、MySQLは書き込み操作を処理する単一のプライマリサーバー(ほとんどの場合、最初のグループメンバー)を指定します。 マルチプライマリグループを使用すると、任意のグループメンバーが書き込みを実行できます。

マルチプライマリグループを構成する場合は、loose-group_replication_single_primary_modeおよびloose-group_replication_enforce_update_everywhere_checksディレクティブのコメントを解除します。 これにより、マルチプライマリグループが設定されます。 単一のプライマリグループの場合は、次の2行にコメントを付けたままにします。

/etc/mysql/my.cnf

. . .
# Single or Multi-primary mode? Uncomment these two lines
# for multi-primary mode, where any host can accept writes
#loose-group_replication_single_primary_mode = OFF
#loose-group_replication_enforce_update_everywhere_checks = ON
. . .

これらの設定は、各MySQLサーバーで同じである必要があります。

この設定は後で変更できますが、変更した後、MySQLグループの各メンバーを再起動する必要があります。 新しい構成に切り替えるには、グループ内の各MySQLインスタンスを停止し、新しい設定で各メンバーを起動してから、グループレプリケーションを再ブートストラップする必要があります。 これはデータに影響を与えませんが、ダウンタイムの小さなウィンドウが必要です。

ホスト固有の構成設定

4番目のセクションには、次のような各サーバーで異なる設定が含まれています。

  • サーバーID
  • バインドするアドレス
  • 他のメンバーに報告するアドレス
  • ローカルレプリケーションアドレスとリスニングポート

server_idディレクティブは一意の番号に設定する必要があります。 最初のメンバーの場合、これを1に設定し、追加のホストごとに番号を増やします。 bind-addressreport_hostをそれぞれのサーバーのIPアドレスに設定して、MySQLインスタンスが外部接続をリッスンし、そのアドレスを他のホストに正しく報告するようにします。 loose-group_replication_local_addressも、IPアドレスにグループレプリケーションポート(33061)を追加して、現在のサーバーのIPアドレスに設定する必要があります。

例として、サンプルIPアドレスを使用したmember1の構成のこの部分を次に示します。

/etc/mysql/my.cnf

. . .
# Host specific replication configuration
server_id = 1
bind-address = "203.0.113.1"
report_host = "203.0.113.1"
loose-group_replication_local_address = "203.0.113.1:33061"

各MySQLサーバーでこのプロセスを完了します。 member2の構成は次のとおりです。

/etc/mysql/my.cnf

. . .
# Host specific replication configuration
server_id = 2
bind-address = "203.0.113.2"
report_host = "203.0.113.2"
loose-group_replication_local_address = "203.0.113.2:33061"

member3の構成は次のとおりです。

/etc/mysql/my.cnf

. . .
# Host specific replication configuration
server_id = 3
bind-address = "203.0.113.3"
report_host = "203.0.113.3"
loose-group_replication_local_address = "203.0.113.3:33061"

強調表示された各IPアドレスを、構成を編集しているサーバーのIPアドレスに更新してください。

終了したら、共有レプリケーション設定が各ホストで同じであること、およびホスト固有の設定がホストごとにカスタマイズされていることを再確認してください。 終了したら、各ホストでファイルを保存して閉じます。 nanoを使用してファイルを編集した場合は、CTRL + XYENTERの順に押すと編集できます。

これで、各サーバーのMySQL構成ファイルに、MySQLグループレプリケーションをブートストラップするために必要なディレクティブが含まれます。 新しい設定をMySQLインスタンスに適用するには、次のコマンドを使用して、各サーバーでサービスを再起動します。

sudo systemctl restart mysql

これで、各サーバーのファイアウォールルールを更新して、リモートアクセスの有効化に進むことができます。

ステップ3—各サーバーのUFWルールを更新する

前提条件の初期サーバーセットアップガイドに従っていると仮定すると、MySQLをインストールし、OpenSSHUFWプロファイルへのアクセスを有効にした各サーバーにファイアウォールをセットアップします。 これらのファイアウォールは現在、サーバー上の任意のポートへの接続をブロックしているため、これは重要なセキュリティ対策です。ただし、各サーバーのそれぞれのauthorized_keysファイルのキーと一致するキーを提示するssh接続は除きます。

MySQL構成ファイルで、デフォルトのポート3306で外部接続をリッスンするようにサービスを構成しました。 また、33061を、メンバーがレプリケーション調整に使用する必要のあるポートとして定義しました。

各メンバーサーバーで、このグループの他のメンバーが互いに通信できるように、これらのポートの両方へのアクセスを開く必要があります。 member2member1でこれらのポートへのアクセスを開くには、member1で次のufwコマンドを実行します。

sudo ufw allow from member2_server_ip to any port 3306
sudo ufw allow from member2_server_ip to any port 33061

必ずmember2_server_ipを変更して、member2サーバーの実際のIPアドレスを反映させてください。 次に、 member3 の同じポートを開くには、次のコマンドを実行します。

sudo ufw allow from member3_server_ip to any port 3306
sudo ufw allow from member3_server_ip to any port 33061

次に、他の2台のサーバーのファイアウォールルールを更新します。 member2 で次のコマンドを実行し、member1member3のIPアドレスをそれぞれ反映するようにIPアドレスを変更してください。

sudo ufw allow from member1_server_ip to any port 3306
sudo ufw allow from member1_server_ip to any port 33061
sudo ufw allow from member3_server_ip to any port 3306
sudo ufw allow from member3_server_ip to any port 33061

最後に、member3でこれらの2つのコマンドを実行します。 繰り返しになりますが、各サーバーに正しいIPアドレスを入力していることを確認してください。

sudo ufw allow from member1_server_ip to any port 3306
sudo ufw allow from member1_server_ip to any port 33061
sudo ufw allow from member2_server_ip to any port 3306
sudo ufw allow from member2_server_ip to any port 33061

これらのUFWルールを追加すると、3つのMySQLインスタンスのそれぞれが、他の2つのサーバーでMySQLが使用するポートへのアクセスを許可されます。

MySQLポートへのアクセスが開いた状態で、レプリケーションユーザーを作成し、グループレプリケーションプラグインを有効にできます。

ステップ4—レプリケーションユーザーの設定とグループレプリケーションプラグインの有効化

レプリケーショングループ内の他のサーバーとの接続を確立するには、各MySQLインスタンスに専用のレプリケーションユーザーが必要です。

各MySQLサーバーで、管理ユーザーを使用してMySQLインスタンスにログインし、対話型セッションを開始します。

sudo mysql

:このセクションの各コマンドは、各MySQLインスタンスで必ず実行してください。


各サーバーには独自のレプリケーションユーザーが存在するため、作成プロセス中にバイナリロギングをオフにする必要があります。 そうしないと、レプリケーションが開始されると、グループはレプリケーションユーザーをプライマリサーバーから他のサーバーに伝播しようとし、既に配置されているレプリケーションユーザーとの競合を引き起こします。 各サーバーでMySQLプロンプトから次のコマンドを実行します。

SET SQL_LOG_BIN=0;

これで、CREATE USERステートメントを実行して、レプリケーションユーザーを作成できます。 次のコマンドを実行すると、replという名前のユーザーが作成されます。 このコマンドは、レプリケーションユーザーがSSLを使用して接続する必要があることを指定します。 また、このレプリケーションユーザーを作成するときは、passwordの代わりに安全なパスワードを使用してください。

CREATE USER 'repl'@'%' IDENTIFIED BY 'password' REQUIRE SSL;

次に、サーバーで新しいユーザーのレプリケーション権限を付与します。

GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

次に、特権をフラッシュして変更を実装します。

FLUSH PRIVILEGES;

その後、バイナリロギングを再度有効にして、通常の操作を再開します。

SET SQL_LOG_BIN=1;

次に、group_replication_recoveryチャネルを設定して、新しいレプリケーションユーザーとそれに関連付けられたパスワードを使用します。 次に、各サーバーはこれらの資格情報を使用してグループへの認証を行います。

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

:8.0.23より古いバージョンのMySQLを使用している場合、これを設定するにはMySQLのレガシー構文を使用する必要があります。

CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery';

レプリケーションユーザーを配置したら、group_replicationプラグインを有効にして、グループを初期化する準備をすることができます。

INSTALL PLUGIN group_replication SONAME 'group_replication.so';

次のコマンドを実行して、プラグインがアクティブであることを確認します。

SHOW PLUGINS;

group_replicationプラグインは、最近追加されたプラグインであるため、リストの一番下に表示されます。

Output+----------------------------+----------+--------------------+----------------------+---------+
| Name                       | Status   | Type               | Library              | License |
+----------------------------+----------+--------------------+----------------------+---------+
|                            |          |                    |                      |         |
| . . .                      | . . .    | . . .              | . . .                | . . .   |
|                            |          |                    |                      |         |
| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
+----------------------------+----------+--------------------+----------------------+---------+
45 rows in set (0.00 sec)

この出力は、プラグインがロードされ、現在アクティブであることを確認します。 次のステップに進む前に、各MySQLインスタンスでこのセクションの各コマンドを実行したことを確認してください。

ステップ5—グループレプリケーションを開始する

これで、各MySQLサーバーにレプリケーションユーザーが構成され、グループレプリケーションプラグインが有効になりました。これで、グループの起動を開始できます。

最初のノードのブートストラップ

グループを起動するには、グループの単一メンバーで次の手順を実行します。 デモンストレーションの目的で、このガイドはmember1でこれらの手順を完了します

グループメンバーは、最初にグループに参加するときに、レプリケーションデータ、最新のメンバーシップリスト、およびその他の情報を送信するために既存のメンバーに依存しています。 このため、シードリスト内の他のメンバーからこの情報を期待しないように、最初のグループメンバーを起動するために少し異なる手順を使用する必要があります。

設定されている場合、group_replication_bootstrap_group変数は、ピアからの情報の受信を期待してはならず、代わりに新しいグループを確立して自分自身をプライマリメンバーに選択する必要があることをメンバーに通知します。 この変数は、次のコマンドでオンにできます。

SET GLOBAL group_replication_bootstrap_group=ON;

次に、最初のグループメンバーのレプリケーションを開始できます。

START GROUP_REPLICATION;

その後、group_replication_bootstrap_group変数をOFFに戻すことができます。これが適切なのは、既存のグループメンバーがいない場合だけだからです。

SET GLOBAL group_replication_bootstrap_group=OFF;

グループは、このサーバーを唯一のメンバーとして開始されます。 performance_schemaデータベースのreplication_group_membersテーブル内のエントリを確認して、これを確認します。

SELECT * FROM performance_schema.replication_group_members;

このクエリは、現在のホストを表す単一の行を返します。

Output+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST   | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1  |        3306 | ONLINE       | PRIMARY     | 8.0.28         | XCom                       |
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+
1 row in set (0.00 sec)

MEMBER_STATEONLINE値は、このノードがグループ内で完全に動作していることを示します。

次に、いくつかのサンプルデータを使用してテストデータベースとテーブルを作成します。 このグループにさらにメンバーが追加されると、このデータは自動的にそれらに複製されます。

playgroundという名前のサンプルデータベースを作成することから始めます。

CREATE DATABASE playground;

次に、次のコマンドを使用して、playgroundデータベース内にequipmentという名前のサンプルテーブルを作成します。

CREATE TABLE playground.equipment ( 
id INT NOT NULL AUTO_INCREMENT,
type VARCHAR(50),
quant INT,
color VARCHAR(25),
PRIMARY KEY(id)
);

このテーブルには、次の4つの列が含まれています。

  • id:この列には、自動的に増分する整数値が含まれます。つまり、サンプルデータをテーブルにロードするときに、この列の値を指定する必要はありません。
  • type:この列には、行が表す遊具の種類を説明する文字列値が含まれます
  • quant:この列には、特定のタイプの遊具の数量を表す整数値が含まれます
  • color:この列には、特定の機器の色を指定する文字列値が保持されます

また、このテーブルの主キーとしてid列が指定されていることに注意してください。 MySQLでは、グループに複製されるすべてのテーブルには、テーブルの主キーとして指定された列が必要です。

最後に、次のコマンドを実行して、1行のデータをテーブルに挿入します。

INSERT INTO playground.equipment (type, quant, color) VALUES ("slide", 2, "blue");

テーブルをクエリして、データが正しく入力されていることを確認します。

SELECT * FROM playground.equipment;
Output+----+-------+-------+-------+
| id | type  | quant | color |
+----+-------+-------+-------+
|  1 | slide |     2 | blue  |
+----+-------+-------+-------+
1 row in set (0.00 sec)

このサーバーがグループのメンバーであり、書き込み機能があることを確認した後、他のサーバーはグループに参加できます。

残りのノードの起動

次に、member2でグループレプリケーションを開始します。 すでにアクティブなメンバーがいるので、グループをブートストラップする必要はなく、このメンバーはすぐに参加できます。

START GROUP_REPLICATION;

member3 で、同じ方法でグループレプリケーションを開始します。

START GROUP_REPLICATION;

3台のサーバーのいずれかでメンバーシップリストを再度確認してください。 今回は、出力に3つのサーバーがリストされます。

SELECT * FROM performance_schema.replication_group_members;
Output
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST   | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1  |        3306 | ONLINE       | PRIMARY     | 8.0.28         | XCom                       |
| group_replication_applier | 1ae4b211-1b01-11e7-9d89-ceb93e1d5494 | 203.0.113.2  |        3306 | ONLINE       | SECONDARY   | 8.0.28         | XCom                       |
| group_replication_applier | 157b597a-1b01-11e7-9d83-566a6de6dfef | 203.0.113.3  |        3306 | ONLINE       | SECONDARY   | 8.0.28         | XCom                       |
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+
3 rows in set (0.00 sec)

すべてのメンバーは、MEMBER_STATEの値がONLINEである必要があります。 新しいグループの場合、いずれかのノードがRECOVERINGとして数秒以上表示される場合は、通常、エラーが発生したか、何かが正しく構成されていないことを示しています。 /var/log/mysql/error.logのログを確認して、問題の原因に関する追加情報を入手してください。

次に、テストデータベース情報が新しいメンバーに複製されているかどうかを確認します。

SELECT * FROM playground.equipment;
Output+----+-------+-------+-------+
| id | type  | quant | color |
+----+-------+-------+-------+
|  1 | slide |     2 | blue  |
+----+-------+-------+-------+
1 row in set (0.01 sec)

新しいメンバーでデータが利用できる場合は、グループレプリケーションが正しく機能していることを意味します。

ステップ6—新しいグループメンバーの書き込み機能をテストする

次に、新しいレプリケーショングループメンバーからデータベースへの書き込みを試すことができます。 これが成功するかどうかは、単一のプライマリグループまたはマルチプライマリグループのどちらを構成するかによって決まります。

単一のプライマリ環境での書き込みのテスト

単一のプライマリグループでは、一貫性の理由から、非プライマリサーバーからの書き込み操作が拒否されることを期待する必要があります。 レプリケーショングループの任意のメンバーに対して次のクエリを実行することにより、いつでも現在のプライマリを見つけることができます。

SHOW STATUS LIKE '%primary%';
Output+----------------------------------+--------------------------------------+
| Variable_name                    | Value                                |
+----------------------------------+--------------------------------------+
| group_replication_primary_member | 13324ab7-1b01-11e7-9dd1-22b78adaa992 |
+----------------------------------+--------------------------------------+
1 row in set (0.01 sec)

クエリの値はMEMBER_IDになり、以前と同じようにグループメンバーリストをクエリすることでホストと照合できます。

SELECT * FROM performance_schema.replication_group_members;
Output+---------------------------+--------------------------------------+--------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1  |        3306 | ONLINE       |
| group_replication_applier | 1ae4b211-1b01-11e7-9d89-ceb93e1d5494 | 203.0.113.2  |        3306 | ONLINE       |
| group_replication_applier | 157b597a-1b01-11e7-9d83-566a6de6dfef | 203.0.113.3  |        3306 | ONLINE       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
3 rows in set (0.01 sec)

この出力例が示すように、203.0.113.1member1 —のホストは現在プライマリサーバーです。 別のメンバーからデータベースに書き込もうとすると、操作は失敗します。

INSERT INTO playground.equipment (type, quant, color) VALUES ("swing", 10, "yellow");
OutputERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement

グループは現在、単一の書き込み可能なプライマリで構成されているため、これは予想されます。 プライマリサーバーに問題があり、グループを離れると、グループは自動的に新しいメンバーをプライマリとして選択し、書き込みを受け入れます。

マルチプライマリ環境での書き込みのテスト

マルチプライマリ指向で構成されたグループの場合、すべてのメンバーがデータベースへの書き込みをコミットできる必要があります。

group_replication_primary_member変数の値を再度確認することにより、グループがマルチプライマリモードで動作していることを再確認できます。

SHOW STATUS LIKE '%primary%';
Output+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| group_replication_primary_member |       |
+----------------------------------+-------+
1 row in set (0.02 sec)

変数が空の場合、これは指定されたプライマリホストがなく、すべてのメンバーが書き込みを受け入れることができる必要があることを意味します。

equipmentテーブルにデータを書き込もうとして、member2でこれをテストします。

INSERT INTO playground.equipment (type, quant, color) VALUES ("swing", 10, "yellow");
OutputQuery OK, 1 row affected (0.00 sec)

member2はエラーなしで書き込み操作をコミットしました。

member3 で、次のクエリを実行して、新しいアイテムが追加されたかどうかを確認します。

SELECT * FROM playground.equipment;
Output+----+-------+-------+--------+
| id | type  | quant | color  |
+----+-------+-------+--------+
|  1 | slide |     2 | blue   |
|  2 | swing |    10 | yellow |
+----+-------+-------+--------+
2 rows in set (0.00 sec)

これにより、member2の書き込みが正常に複製されたことが確認されます。

次に、次のINSERTステートメントを実行して、member3の書き込み機能をテストします。

INSERT INTO playground.equipment (type, quant, color) VALUES ("seesaw", 3, "green");
OutputQuery OK, 1 row affected (0.02 sec)

member1 に戻り、テストして、両方の新しいメンバーからの書き込み操作が複製されていることを確認します。

SELECT * FROM playground.equipment;
Output+----+--------+-------+--------+
| id | type   | quant | color  |
+----+--------+-------+--------+
|  1 | slide  |     2 | blue   |
|  2 | swing  |    10 | yellow |
|  3 | seesaw |     3 | green  |
+----+--------+-------+--------+
3 rows in set (0.01 sec)

これにより、レプリケーションが各方向で機能し、各メンバーが書き込み操作を実行できることが確認されます。

ステップ7—グループをバックアップする

グループがブートストラップされると、プライマリサーバーを選択するのに十分なメンバーがいる限り、個々のメンバーは可用性に影響を与えることなく参加および離脱できます。 ただし、特定の構成変更が行われた場合(シングルプライマリ環境とマルチプライマリ環境の切り替えなど)、またはグループのすべてのメンバーが離脱した場合は、最初に行ったのと同じ方法でグループを再ブートストラップする必要があります。

member1 で、group_replication_bootstrap_group変数をONに設定します。

SET GLOBAL GROUP_REPLICATION_BOOTSTRAP_GROUP=ON;

次に、グループを初期化します。

START GROUP_REPLICATION;

その後、group_replication_bootstrap_group変数をOFFに戻すことができます。

SET GLOBAL GROUP_REPLICATION_BOOTSTRAP_GROUP=OFF;

最初のメンバーがグループを開始すると、他のメンバーが参加できます。

START GROUP_REPLICATION;

追加のメンバーについては、次のプロセスに従ってください。

START GROUP_REPLICATION;

これで、グループがオンラインになり、すべてのメンバーが利用可能になります。

SELECT * FROM performance_schema.replication_group_members;
Output+---------------------------+--------------------------------------+--------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1  |        3306 | ONLINE       |
| group_replication_applier | 1ae4b211-1b01-11e7-9d89-ceb93e1d5494 | 203.0.113.2  |        3306 | ONLINE       |
| group_replication_applier | 157b597a-1b01-11e7-9d83-566a6de6dfef | 203.0.113.3  |        3306 | ONLINE       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
3 rows in set (0.01 sec)

このプロセスは、必要に応じてグループを再開するために使用できます。

ステップ8—MySQLの起動時にグループに自動的に参加する

現在の設定では、メンバーサーバーが再起動しても、起動時にグループに自動的に再参加することはありません。 メンバーが自動的にグループに再参加するようにする場合は、構成ファイルを少し変更できます。

この手順で概説されている設定は、メンバーが起動時に自動的に参加するようにする場合に役立ちます。 ただし、注意すべき点がいくつかあります。 まず、この設定は、MySQLインスタンス自体が起動されたときにのみ影響します。 タイムアウトの問題のためにメンバーがグループから削除されたが、MySQLインスタンスがオンラインのままである場合、メンバーは自動的に再参加しません。

次に、グループを最初にブートストラップするときにこの設定を有効にすると、害を及ぼす可能性があります。 参加する既存のグループがない場合、MySQLプロセスは、他の存在しないメンバーに接続して初期化しようとするため、開始に長い時間がかかります。 長いタイムアウトの後でのみ、それはあきらめて正常に開始します。 その後、上記の手順を使用してグループをブートストラップする必要があります。

上記の注意事項を念頭に置いて、MySQLの起動時にノードがグループに自動的に参加するように構成する場合は、メインのMySQL構成ファイルを開きます。

sudo nano /etc/mysql/my.cnf

内部で、loose-group_replication_start_on_boot変数を見つけて、ONに設定します。

/etc/mysql/my.cnf

[mysqld]
. . .
loose-group_replication_start_on_boot = ON
. . .

終了したら、ファイルを保存して閉じます。 メンバーは、次にMySQLインスタンスが開始されたときに、自動的にグループへの参加を試みる必要があります。

結論

このチュートリアルを完了することで、3台のUbuntu20.04サーバー間でMySQLグループレプリケーションを構成する方法を学びました。 シングルプライマリ設定の場合、メンバーは必要に応じて書き込み可能なプライマリを自動的に選択します。 マルチプライマリグループの場合、すべてのメンバーが書き込みと更新を実行できます。

グループレプリケーションは、メンバーが自由に参加または離脱できるようにすると同時に、データの一貫性とメッセージの順序に関する保証を提供する柔軟なレプリケーショントポロジを提供します。 MySQLグループレプリケーションは、構成が少し複雑になる場合がありますが、従来のレプリケーションでは不可能な機能を提供します。