この記事では、InnoDB Cluster に災害復旧機能を提供する InnoDB ClusterSet 環境の基本的な設定方法を紹介します。InnoDB ClusterSet は、主となる InnoDB Cluster をバックアップ位置または別のデータセンターにある 1 つ以上のレプリカと関連付けることで、InnoDB Cluster デプロイメントに災害復旧能力を追加します。InnoDB ClusterSet は、特定の ClusterSet 非同期レプリケーションチャネルを介して、主クラスタからレプリカクラスタへのレプリケーションを自動的に管理します。主クラスタがネットワーク接続の喪失やデータセンターの問題によりアクセスできなくなった場合、レプリカクラスタをその位置でアクティブ化できます。
それでは、正確なトポロジを構成する方法を詳しく見ていきましょう。
この設定には、MySQLShell ユーティリティによって提供されるサンドボックス環境を使用しました。
環境計画
| プライマリクラスタ | 127.0.0.1:3308 127.0.0.1:3309 127.0.0.1:3310 |
|---|---|
| レプリカクラスタ | 127.0.0.1:3311 127.0.0.1:3312 127.0.0.1:3313 |
| ルーター | 127.0.0.1:6446/6447 |
最初のクラスタ(「primaryCluster」)の設定
- サンドボックスのデプロイ
MySQL JS > dba.deploySandboxInstance(3308)
MySQL JS > dba.deploySandboxInstance(3309)
MySQL JS > dba.deploySandboxInstance(3310)
- 次に、クラスタを起動する前にいくつかの事前チェックを実行する必要があります。
### 関連ノードにそれぞれ接続します。
MySQL JS > shell.connect('admin@localhost:3308')
MySQL localhost:3308 ssl JS > shell.connect('admin@localhost:3309')
MySQL localhost:3309 ssl JS > shell.connect('admin@localhost:3310')
### 以下のコマンドは、InnoDBクラスタの要件(グループレプリケーション設定)を満たしているかどうかをチェックし、不足している要件を自動的に修正します。ここでは、クラスタデプロイメント用に新しいユーザー「clusterAdmin」を設定しました。
MySQL localhost:3308 ssl JS > dba.checkInstanceConfiguration('admin@localhost:3308')
MySQL localhost:3308 ssl JS > dba.configureInstance('admin@127.0.0.1:3308',{clusterAdmin: 'clusterAdmin', clusterAdminPassword: 'Admin@1234'})
MySQL localhost:3309 ssl JS > dba.checkInstanceConfiguration('admin@localhost:3309')
MySQL localhost:3309 ssl JS > dba.configureInstance('admin@127.0.0.1:3309',{clusterAdmin: 'clusterAdmin', clusterAdminPassword: 'Admin@1234'})
MySQL localhost:3310 ssl JS > dba.checkInstanceConfiguration('admin@localhost:3310')
MySQL localhost:3310 ssl JS > dba.configureInstance('admin@127.0.0.1:3310',{clusterAdmin: 'clusterAdmin', clusterAdminPassword: 'Admin@1234'})
すべてのインスタンスが準備できたら、シードノードを使用してクラスタを作成できます。「createCluster」コマンドは、グループレプリケーションを初期化するすべての隠れたステップを実行し、その後、他のノードが分散リカバリ/クローンプラグインを介してそのグループに参加します。
InnoDB クラスタはグループレプリケーション上に構築されており、(自動メンバーシップ管理、フォールトトレランス、自動フェイルオーバー)を提供します。これにより、災害復旧サポートを備えた複雑なトポロジをデプロイ/管理するためのシンプルなインターフェースが提供されます。
- 初期ノード(「localhost:3308」)を使用してクラスタをブートストラップします。
MySQL localhost:3310 ssl JS > shell.connect('clusterAdmin@localhost:3308')
MySQL localhost:3308 ssl JS > primaryCluster = dba.createCluster('primaryCluster')
MySQL localhost:3308 ssl JS > primaryCluster = dba.getCluster()
出力:
MySQL localhost:3308 ssl JS > primaryCluster.status()
{
"clusterName": "primaryCluster",
"defaultReplicaSet": {
"name": "default",
"primary": "127.0.0.1:3308",
"ssl": "REQUIRED",
"status": "OK_NO_TOLERANCE",
"statusText": "クラスタはいかなる障害にも耐えられません。",
"topology": {
"127.0.0.1:3308": {
"address": "127.0.0.1:3308",
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.31"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "127.0.0.1:3308"
}
- ここで、最初のノードのブートストラップに成功しました。次に、他のノードが CLONE プラグインを使用してクラスタに参加します。
MySQL localhost:3308 ssl JS > primaryCluster.addInstance("clusterAdmin@localhost:3309",{password:'Admin@1234'})
出力:
* クローンの完了を待っています...
注: 127.0.0.1:3309 は 127.0.0.1:3308 からクローンされています
** ステージ DROP DATA: 完了
** クローン転送
ファイルコピー ############################################################ 100% 完了
ページコピー ############################################################ 100% 完了
REDO コピー ############################################################ 100% 完了
注: 127.0.0.1:3309 はシャットダウンしています...
* サーバーの再起動を待っています... 準備完了
* 127.0.0.1:3309 が再起動しました。クローンの完了を待っています...
** ステージ RESTART: 完了
* クローンプロセスが完了しました: 約1秒で73.66 MB転送されました(~73.66 MB/s)
'127.0.0.1:3309' の状態復旧は既に完了しています
インスタンス '127.0.0.1:3309' がクラスタに正常に追加されました。
MySQL localhost:3308 ssl JS > primaryCluster.addInstance("clusterAdmin@localhost:3310",{password:'Admin@1234'})
出力:
* クローンの完了を待っています...
注: 127.0.0.1:3310 は 127.0.0.1:3309 からクローンされています
** ステージ DROP DATA: 完了
** クローン転送
ファイルコピー ############################################################ 100% 完了
ページコピー ############################################################ 100% 完了
REDO コピー ############################################################ 100% 完了
注: 127.0.0.1:3310 はシャットダウンしています...
* サーバーの再起動を待っています... 準備完了
* 127.0.0.1:3310 が再起動しました。クローンの完了を待っています...
** ステージ RESTART: 完了
* クローンプロセスが完了しました: 約1秒で73.66 MB転送されました(~73.66 MB/s)
'127.0.0.1:3310' の状態復旧は既に完了しています
インスタンス '127.0.0.1:3310' がクラスタに正常に追加されました。
- この段階で、最初のクラスタはすべての3つのノードで準備完了です。
MySQL localhost:3308 ssl JS > primaryCluster.status()
出力:
{
"clusterName": "primaryCluster",
"defaultReplicaSet": {
"name": "default",
"primary": "127.0.0.1:3308",
"ssl": "REQUIRED",
"status": "OK",
"statusText": "クラスタはオンラインであり、最大1つの障害に耐えられます。",
"topology": {
"127.0.0.1:3308": {
"address": "127.0.0.1:3308",
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3309": {
"address": "127.0.0.1:3309",
"memberRole": "SECONDARY",
"mode": "R/O",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3310": {
"address": "127.0.0.1:3310",
"memberRole": "SECONDARY",
"mode": "R/O",
"readReplicas": {},
"replicationLag": "applier_queue_applied",
"role": "HA",
"status": "ONLINE",
"version": "8.0.31"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "127.0.0.1:3308"
}
2番目のクラスタ(「replicaCluster」)の設定
- MySQLShell を使用してサンドボックスをデプロイします。
MySQL JS > dba.deploySandboxInstance(3311)
MySQL JS > dba.deploySandboxInstance(3312)
MySQL JS > dba.deploySandboxInstance(3313)
- 同様に、「primaryCluster」ノードに対して行ったように、いくつかの事前チェックを実行します。
# 関連ノードに接続します。
MySQL JS > shell.connect('admin@localhost:3311')
MySQL JS > shell.connect('admin@localhost:3312')
MySQL JS > shell.connect('admin@localhost:3313')
# 以下のコマンドは、InnoDBクラスタの要件(グループレプリケーション設定)を満たしているかどうかをチェックし、不足している要件を自動的に修正します。ここでは、クラスタデプロイメント用に新しいユーザー「clusterAdmin」を設定しました。
MySQL localhost:3308 ssl JS > dba.checkInstanceConfiguration('admin@localhost:3311')
MySQL localhost:3308 ssl JS > dba.configureInstance('admin@127.0.0.1:3311',{clusterAdmin: 'clusterAdmin', clusterAdminPassword: 'Admin@1234'})
MySQL localhost:3308 ssl JS > dba.checkInstanceConfiguration('admin@localhost:3312')
MySQL localhost:3308 ssl JS > dba.configureInstance('admin@127.0.0.1:3312',{clusterAdmin: 'clusterAdmin', clusterAdminPassword: 'Admin@1234'})
MySQL localhost:3308 ssl JS > dba.checkInstanceConfiguration('admin@localhost:3313')
MySQL localhost:3308 ssl JS > dba.configureInstance('admin@127.0.0.1:3313',{clusterAdmin: 'clusterAdmin', clusterAdminPassword: 'Admin@1234'})
- 次に、既存の primaryCluster ノードを介して、ノード(127.0.0.1:3311)で同期をトリガーして ClusterSet トポロジを作成します。ノード(127.0.0.1:3311)は replicaCluster のプライマリノードになり、残りの他のノードはクローン/インクリメンタルプロセスを介してそのノードに参加します。
1)まず、「primaryCluster」ノードに接続します。
MySQL localhost:3308 ssl JS > c clusterAdmin@127.0.0.1:3308
MySQL 127.0.0.1:3308 ssl JS > primaryCluster = dba.getCluster()
2)ここで、「primaryCluster」が ClusterSet トポロジに参加します。
MySQL 127.0.0.1:3308 ssl JS > clusterSet = primaryCluster.createClusterSet('disasterRecoverySet')
出力:
ClusterSet が正常に作成されました。レプリカクラスタを追加するには ClusterSet.createReplicaCluster() を使用してください。
<ClusterSet:disasterRecoverySet>`
3)状態を検証します
MySQL 127.0.0.1:3308 ssl JS > clusterSet.status({extended: 1})
出力:
{
"clusters": {
"primaryCluster": {
"clusterRole": "PRIMARY",
"globalStatus": "OK",
"primary": "127.0.0.1:3308",
"status": "OK",
"statusText": "クラスタはオンラインであり、最大1つの障害に耐えられます。",
"topology": {
"127.0.0.1:3308": {
"address": "127.0.0.1:3308",
"memberRole": "PRIMARY",
"mode": "R/W",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3309": {
"address": "127.0.0.1:3309",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3310": {
"address": "127.0.0.1:3310",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
}
},
"transactionSet": "39c28b63-285a-11ee-a411-5254004d77d3:1-4,59d8e60a-285d-11ee-bb44-5254004d77d3:1-85,59d8f3a6-285d-11ee-bb44-5254004d77d3:1-5"
}
},
"domainName": "disasterRecoverySet",
"globalPrimaryInstance": "127.0.0.1:3308",
"metadataServer": "127.0.0.1:3308",
"primaryCluster": "primaryCluster",
"status": "HEALTHY",
"statusText": "すべてのクラスタが利用可能です。"
}
- これで、ノード(「127.0.0.1:3311」)は既存の「primaryCluster」と非同期プロセスで同期されます。
MySQL 127.0.0.1:3308 ssl JS > c clusterAdmin@127.0.0.1:3311
MySQL 127.0.0.1:3311 ssl JS > replicaCluster = clusterSet.createReplicaCluster("127.0.0.1:3311", "replicaCluster", {recoveryProgress: 1, timeout: 10})
出力:
... レプリカクラスタ 'replicaCluster' が 'disasterRecoverySet' に正常に作成されました。...
- 次に、他のノードがクローンプロセスを介して「replicaCluster」に参加します。
MySQL 127.0.0.1:3311 ssl JS > replicaCluster.addInstance("clusterAdmin@127.0.0.1:3312",{password:'Admin@1234'})
MySQL 127.0.0.1:3311 ssl JS > replicaCluster.addInstance("clusterAdmin@127.0.0.1:3313",{password:'Admin@1234'})
- 最後に、クラスタ環境の状態を確認します。
MySQL 127.0.0.1:3311 ssl JS > clusterSet = dba.getClusterSet()
MySQL 127.0.0.1:3311 ssl JS > clusterSet.status({extended: 1})
出力:
{
"clusters": {
"primaryCluster": {
"clusterRole": "PRIMARY",
"globalStatus": "OK",
"primary": "127.0.0.1:3308",
"status": "OK",
"statusText": "クラスタはオンラインであり、最大1つの障害に耐えられます。",
"topology": {
"127.0.0.1:3308": {
"address": "127.0.0.1:3308",
"memberRole": "PRIMARY",
"mode": "R/W",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3309": {
"address": "127.0.0.1:3309",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3310": {
"address": "127.0.0.1:3310",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
}
},
"transactionSet": "39c28b63-285a-11ee-a411-5254004d77d3:1-4,59d8e60a-285d-11ee-bb44-5254004d77d3:1-124,59d8f3a6-285d-11ee-bb44-5254004d77d3:1-5"
},
"replicaCluster": {
"clusterRole": "REPLICA",
"clusterSetReplication": {
"applierStatus": "APPLIED_ALL",
"applierThreadState": "Coordinatorからのイベントを待っています",
"applierWorkerThreads": 4,
"receiver": "127.0.0.1:3311",
"receiverStatus": "ON",
"receiverThreadState": "ソースからイベントを送信するのを待っています",
"source": "127.0.0.1:3308"
},
"clusterSetReplicationStatus": "OK",
"globalStatus": "OK",
"status": "OK",
"statusText": "クラスタはオンラインであり、最大1つの障害に耐えられます。",
"topology": {
"127.0.0.1:3311": {
"address": "127.0.0.1:3311",
"memberRole": "PRIMARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.0.1:3312": {
"address": "127.0.0.1:3312",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3313": {
"address": "127.0.0.1:3313",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
}
},
"transactionSet": "2e71122e-2862-11ee-b81c-5254004d77d3:1-5,39c28b63-285a-11ee-a411-5254004d77d3:1-4,59d8e60a-285d-11ee-bb44-5254004d77d3:1-124,59d8f3a6-285d-11ee-bb44-5254004d77d3:1-5",
"transactionSetConsistencyStatus": "OK",
"transactionSetErrantGtidSet": "",
"transactionSetMissingGtidSet": ""
}
},
"domainName": "disasterRecoverySet",
"globalPrimaryInstance": "127.0.0.1:3308",
"metadataServer": "127.0.0.1:3308",
"primaryCluster": "primaryCluster",
"status": "HEALTHY",
"statusText": "すべてのクラスタが利用可能です。"
}
ここで、ClusterSet トポロジはすべての6つのノードを含む準備ができています。
ルーターユーザーの設定
次の段階では、新しく作成した ClusterSet 環境を使用して MySQLRouter をブートストラップします:
- まず、MySQLRouter の監視/管理に専用のユーザーを生成します。
MySQL 127.0.0.1:3311 ssl JS > c clusterAdmin@localhost:3308
MySQL localhost:3308 ssl JS > primaryCluster = dba.getCluster();
MySQL localhost:3308 ssl JS > primaryCluster.setupRouterAccount('routerUser')
出力:
新しいアカウント routerUser@% のパスワードがありません。提供してください。
新しいアカウントのパスワード: **********
パスワードの確認: **********
ユーザー routerUser@% を作成しています。
アカウント routerUser@% が正常に作成されました。
- ユーザー(「routerUser」)とルーター名(「routerInstance」)を使用してルーターをブートストラップします。
[vagrant@localhost ~]$ sudo mysqlrouter --bootstrap clusterAdmin@127.0.0.1:3308 --account=routerUser --name='routerInstance' --user root --force
ここで --force を使用しているのは、--force なしでは mysqlrouter がクラスタセットを認識できないためです。これにより、既存のクラスタセットが再構成されます。
ここで、後でデータベースに接続したりサービスを管理したりするために役立ついくつかの有用な情報が表示されます。
# MySQL Router 'routerInstance' が 'disasterRecoverySet' に設定されました
この MySQL Router が生成された構成で起動された後
$ /etc/init.d/mysqlrouter restart
または
$ systemctl start mysqlrouter
または
$ mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf
ClusterSet 'disasterRecoverySet' は、以下に接続することでアクセスできます:
## MySQL Classic プロトコル
- 読み書き接続: localhost:6446
- 読み取り専用接続: localhost:6447
## MySQL X プロトコル
- 読み書き接続: localhost:6448
- 読み取り専用接続: localhost:6449
- 最後に、mysqlrouter サービスを起動します:
sudo mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf &
接続ルーティングの検証
- ルーター ポート「6446」に接続し、いくつかのデモ テーブル/データを作成します:
shell> mysql -h 127.0.0.1 -u root -pRoot@1234 -P 6446 -e "create database demoDB;use demoDB;create table demoTable (id int(10) not null auto_increment primary key, data varchar(50));insert into demoTable(data) values('sample');"
- 読み取り用にルーター ポート「6447」に接続します。ここでは、デフォルトで接続は主クラスタ(primaryCluster)のノード数の間でロードバランスが取られます。
[vagrant@localhost ~]$ mysql -h 127.0.0.1 -u root -pRoot@1234 -P 6447 -e "use demoDB;select * from demoTable;select @@server_id;"
+----+--------+
| id | data |
+----+--------+
| 1 | sample |
+----+--------+
+-------------+
| @@server_id |
+-------------+
| 194452202 |
+-------------+
[vagrant@localhost ~]$ mysql -h 127.0.0.1 -u root -pRoot@1234 -P 6447 -e "use demoDB;select * from demoTable;select @@server_id;"
+----+--------+
| id | data |
+----+--------+
| 1 | sample |
+----+--------+
+-------------+
| @@server_id |
+-------------+
| 2376678236 |
+-------------+
[vagrant@localhost ~]$ mysql -h 127.0.0.1 -u root -pRoot@1234 -P 6447 -e "use demoDB;select * from demoTable;select @@server_id;"
mysql: [警告] コマンドライン インターフェイスでパスワードを使用すると安全でない可能性があります。
+----+--------+
| id | data |
+----+--------+
| 1 | sample |
+----+--------+
+-------------+
| @@server_id |
+-------------+
| 194452202 |
+-------------+
したがって、デフォルトでは、すべての接続がデフォルトの「プライマリ」クラスタにルーティングされます。この例では「primaryCluster」ですが、要件に応じて主要コンポーネントを変更できます。
ClusterSet トポロジの変更
MySQL localhost:3308 ssl JS > clusterSet=dba.getClusterSet()
MySQL localhost:3308 ssl JS > clusterSet.status({extended:1})
出力
<ClusterSet:disasterRecoverySet>
{
"clusters": {
"primaryCluster": {
"clusterRole": "PRIMARY",
"globalStatus": "OK",
"primary": "127.0.0.1:3308",
"status": "OK",
"statusText": "クラスタはオンラインであり、最大1つの障害に耐えられます。",
"topology": {
"127.0.0.1:3308": {
"address": "127.0.0.1:3308",
"memberRole": "PRIMARY",
"mode": "R/W",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3309": {
"address": "127.0.0.1:3309",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3310": {
"address": "127.0.0.1:3310",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
}
},
"transactionSet": "39c28b63-285a-11ee-a411-5254004d77d3:1-4,59d8e60a-285d-11ee-bb44-5254004d77d3:1-143,59d8f3a6-285d-11ee-bb44-5254004d77d3:1-5"
},
"replicaCluster": {
"clusterRole": "REPLICA",
"clusterSetReplication": {
"applierStatus": "APPLIED_ALL",
"applierThreadState": "Coordinatorからのイベントを待っています",
"applierWorkerThreads": 4,
"receiver": "127.0.0.1:3311",
"receiverStatus": "ON",
"receiverThreadState": "ソースからイベントを送信するのを待っています",
"source": "127.0.0.1:3308"
},
"clusterSetReplicationStatus": "OK",
"globalStatus": "OK",
"status": "OK",
"statusText": "クラスタはオンラインであり、最大1つの障害に耐えられます。",
"topology": {
"127.0.0.1:3311": {
"address": "127.0.0.1:3311",
"memberRole": "PRIMARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3312": {
"address": "127.0.0.1:3312",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3313": {
"address": "127.0.0.1:3313",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
}
},
"transactionSet": "2e71122e-2862-11ee-b81c-5254004d77d3:1-5,39c28b63-285a-11ee-a411-5254004d77d3:1-4,59d8e60a-285d-11ee-bb44-5254004d77d3:1-143,59d8f3a6-285d-11ee-bb44-5254004d77d3:1-5",
"transactionSetConsistencyStatus": "OK",
"transactionSetErrantGtidSet": "",
"transactionSetMissingGtidSet": ""
}
},
"domainName": "disasterRecoverySet",
"globalPrimaryInstance": "127.0.0.1:3308",
"metadataServer": "127.0.0.1:3308",
"primaryCluster": "primaryCluster",
"status": "HEALTHY",
"statusText": "すべてのクラスタが利用可能です。"
}
- プライマリクラスタを「primaryCluster」から「replicaCluster」に変更します:
MySQL localhost:3308 ssl JS > clusterSet.setPrimaryCluster('replicaCluster')
出力:
クラスタセットのプライマリクラスタを 'replicaCluster' に切り替えます
* クラスタセットのステータスを検証しています
** クラスタ replicaCluster をチェックしています
クラスタ 'replicaCluster' は利用可能です
** クラスタ primaryCluster をチェックしています
クラスタ 'primaryCluster' は利用可能です
* 5つの内部生成 GTID を再調整しています
* 降格されたクラスタのレプリケーションアカウントを更新しています
* 127.0.0.1:3311 でのトランザクションバックログの同期
** レプリケートされたトランザクション ############################################################ 100%
* メタデータを更新しています
* トポロジを更新しています
** 127.0.0.1:3309 のレプリケーションソースを 127.0.0.1:3311 に変更しています
** 127.0.0.1:3310 のレプリケーションソースを 127.0.0.1:3311 に変更しています
** 127.0.0.1:3308 のレプリケーションソースを 127.0.0.1:3311 に変更しています
* レプリカセットインスタンスでロックを取得しています
** SECONDARIES を事前に同期しています
** プライマリでグローバルロックを取得しています
** SECONDARIES でグローバルロックを取得しています
* プロモートされたプライマリで残りのトランザクションを同期しています
** レプリケートされたトランザクション ############################################################ 100%
* レプリカクラスタを更新しています
クラスタ 'replicaCluster' がクラスタセットのプライマリに昇格されました。プライマリインスタンスは '127.0.0.1:3311' です
- 出力を再度確認すると、「clusterRole:PRIMARY」が「replicaCluster」に移行されたことが観察できます。
MySQL localhost:3308 ssl JS > clusterSet.status({extended:1})
出力:
{
"clusters": {
"primaryCluster": {
"clusterRole": "REPLICA",
"clusterSetReplication": {
"applierStatus": "APPLIED_ALL",
"applierThreadState": "Coordinatorからのイベントを待っています",
"applierWorkerThreads": 4,
"receiver": "127.0.0.1:3308",
"receiverStatus": "ON",
"receiverThreadState": "ソースからイベントを送信するのを待っています",
"source": "127.0.0.1:3311"
},
"clusterSetReplicationStatus": "OK",
"globalStatus": "OK",
"status": "OK",
"statusText": "クラスタはオンラインであり、最大1つの障害に耐えられます。",
"topology": {
"127.0.0.1:3308": {
"address": "127.0.0.1:3308",
"memberRole": "PRIMARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3309": {
"address": "127.0.0.1:3309",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3310": {
"address": "127.0.0.1:3310",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
}
},
"transactionSet": "2e71122e-2862-11ee-b81c-5254004d77d3:1-5,39c28b63-285a-11ee-a411-5254004d77d3:1-4,59d8e60a-285d-11ee-bb44-5254004d77d3:1-145,59d8f3a6-285d-11ee-bb44-5254004d77d3:1-5",
"transactionSetConsistencyStatus": "OK",
"transactionSetErrantGtidSet": "",
"transactionSetMissingGtidSet": ""
},
"replicaCluster": {
"clusterRole": "PRIMARY",
"globalStatus": "OK",
"primary": "127.0.0.1:3311",
"status": "OK",
"statusText": "クラスタはオンラインであり、最大1つの障害に耐えられます。",
"topology": {
"127.0.0.1:3311": {
"address": "127.0.0.1:3311",
"memberRole": "PRIMARY",
"mode": "R/W",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3312": {
"address": "127.0.0.1:3312",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
},
"127.0.0.1:3313": {
"address": "127.0.0.1:3313",
"memberRole": "SECONDARY",
"mode": "R/O",
"replicationLagFromImmediateSource": "",
"replicationLagFromOriginalSource": "",
"status": "ONLINE",
"version": "8.0.31"
}
},
"transactionSet": "2e71122e-2862-11ee-b81c-5254004d77d3:1-5,39c28b63-285a-11ee-a411-5254004d77d3:1-4,59d8e60a-285d-11ee-bb44-5254004d77d3:1-145,59d8f3a6-285d-11ee-bb44-5254004d77d3:1-5"
}
},
"domainName": "disasterRecoverySet",
"globalPrimaryInstance": "127.0.0.1:3311",
"metadataServer": "127.0.0.1:3311",
"primaryCluster": "replicaCluster",
"status": "HEALTHY",
"statusText": "すべてのクラスタが利用可能です。"
}
ここまでで、プライマリコンポーネントを primaryCluster から replicaCluster に変更しましたが、ルーティングはまだ primaryCluster に設定されています。replicaCluster にトラフィックを送信するには、ルーティングオプションも変更する必要があります。
MySQL localhost:3308 ssl JS > clusterSet.listRouters()
出力:
{"domainName":"disasterRecoverySet","routers":{"localhost.localdomain::routerInstance":{"hostname":"localhost.localdomain","lastCheckIn":"2023-07-22 02:47:42","roPort":"6447","roXPort":"6449","rwPort":"6446","rwXPort":"6448","targetCluster":"primary","version":"8.0.32"},
- 接続先を「primaryCluster」から「replicaCluster」に変更します:
MySQL localhost:3308 ssl JS > clusterSet.setRoutingOption('localhost.localdomain::routerInstance', 'target_cluster', 'replicaCluster')
MySQL localhost:3308 ssl JS > clusterSet.listRouters()
出力:
MySQL localhost:3308 ssl JS > clusterSet.listRouters()
{
"domainName": "disasterRecoverySet",
"routers": {
"localhost.localdomain::routerInstance": {
"hostname": "localhost.localdomain",
"lastCheckIn": "2023-07-22 02:47:42",
"roPort": "6447",
"roXPort": "6449",
"rwPort": "6446",
"rwXPort": "6448",
"targetCluster": "replicaCluster",
"version": "8.0.32"
}
}
}
既存のクラスタセットでのルーティング戦略の検証
MySQL localhost:3308 ssl JS > clusterSet.routingOptions()
出力:
{
"domainName": "disasterRecoverySet",
"global": {
"invalidated_cluster_policy": "drop_all",
"stats_updates_frequency": 0,
"target_cluster": "primary"
},
"routers": {
"localhost.localdomain::routerInstance": {
"target_cluster": "replicaCluster"
}
}
}
主クラスタが利用できない場合やアクセスできない場合があります。このような状況では、アプリケーションがブロックされるのを避けるために、緊急フェイルオーバーを実行するのが直接的な解決策です。
緊急フェイルオーバーは、InnoDB ClusterSet デプロイメントで選択したレプリカクラスタに主 InnoDB クラスタを切り替えるプロセスです。緊急フェイルオーバープロセス中は、非同期レプリケーションなどのネットワーク要因によりデータの一貫性が保証されないため、安全のためにフェイルオーバープロセス中に元の主クラスタが無効としてマークされます。
したがって、元の主クラスタがまだオンラインである場合、それをシャットダウンする必要があります。後で、無効な主クラスタは、再参加/修復プロセスを介してクラスタセットに再参加できます。
緊急フェイルオーバーの実行
clusterSet.forcePrimaryCluster("replicaCluster")
clusterSet.setRoutingOption('localhost::routerInstance', 'target_cluster', 'replicaCluster')