本記事は Create an InnoDB Replica Set With MySQL Shell の翻訳版です。

MySQL Shellを使うことで、InnoDB ReplicaSetを簡単に短時間で作成できます。複数のコマンドを実行するだけで、ReplicaSetの作成からセカンダリ・インスタンスの追加、プライマリ・インスタンスからセカンダリ・インスタンスへのデータのクローンまで行うことができます。本記事ではそのやり方をご紹介します。

 

前提条件

本実施例では、ポート5555と5556をMySQL Sandboxインスタンスに割り当て、ポート5555で実行するインスタンスをプライマリ・インスタンス、ポート5556で実行するインスタンスをセカンダリ・インスタンスとします。ポート5555のプライマリ・インスタンスにmysql_shortsというスキーマを用意しこのデータをレプリケートします。

MySQL Sandboxインスタンスについては、関連ブログおよび公式Webマニュアルをご覧下さい。

 

プライマリ・インスタンス(ポート5555)のスキーマは下記です。

show schemas;
+—————————–+
| Database                                |
+—————————–+
| information_schema           |
| mysql                                      |
| mysql_shorts                         |
| performance_schema          |
| sys                                            |
+—————————–+

 

セカンダリ・インスタンス(ポート5556)のスキーマは下記です。

show schemas;
+—————————–+
| Database                                |
+—————————–+
| information_schema            |
| mysql                                       |
| performance_schema          |
| sys                                            |
+—————————–+

 

上記で表示した通り本実施例においてReplicaSet作成前の段階では、プライマリ・インスタンス(ポート5555)に存在するスキーマmysql_shortsが、セカンダリ・インスタンス(ポート5556)にはありません。

 

InnoDB ReplicaSet の作成

InnoDB ReplicaSet作成するにはまず、MySQL Shellを使用してプライマリ・インスタンスに接続し、JavaScriptモードで次のコマンドを実行します。

\c root@localhost:5555

var rs = dba.createReplicaSet("demo_set")

上記のコマンドによって作成する新しいInnoDB ReplicaSetを rs と設定します。ReplicaSetの作成を実行すると以下の様なテキストが出力されます。

A new replicaset with instance '127.0.0.1:5555' will be created.
* Checking MySQL instance at 127.0.0.1:5555

This instance reports its own address as 127.0.0.1:5555
127.0.0.1:5555: Instance configuration is suitable.

* Checking connectivity and SSL configuration…
* Updating metadata…

ReplicaSet object successfully created for 127.0.0.1:5555.
Use rs.addInstance() to add more asynchronously replicated instances to this replicaset and rs.status() to check its status.

 

ステータスの確認

下記のコマンドを実行すると、新しく作成したInnoDB ReplicaSetのステータスを確認できます。

rs.status()

実行すると、InnoDB ReplicaSetのステータスがJSONオブジェクトとして表示されます。下記の表示例では、demo_setという名前のInnoDB ReplicaSetにプライマリ・インスタンス(ポート5555)があることを示しています。

{
    "replicaSet": {
        "name": "demo_set",
        "primary": "127.0.0.1:5555",
        "status": "AVAILABLE",
        "statusText": "All instances available.",
        "topology": {
            "127.0.0.1:5555": {
                "address": "127.0.0.1:5555",
                "instanceRole": "PRIMARY",
                "mode": "R/W",
                "status": "ONLINE"
            }
        },
        "type": "ASYNC"
    }
}

 

セカンダリ・インスタンスの追加

InnoDB ReplicaSetには1個以上のセカンダリ・インスタンスが必要です。本実行例では、MySQL Shellをプライマリ・インスタンスに接続した状態から、下記コマンドでセカンダリ・インスタンス(ポート5556)を1個追加します。

rs.addInstance('root@localhost:5556')

上記コマンドはReplicaSet・オブジェクト rs の addInstance() メソッドを呼び出します。このメソッドを呼び出すときは、追加するインスタンスの接続文字列を引数として渡します。上の実行例ではrootユーザを使用して、ポート5556のローカル・システムのインスタンスに接続します。

: 上記では実行例として分かりやすいように、rootユーザーを使用しています。実際の運用システムでは、レプリケーションなどの全てのプロセスでrootを使用するのは、必要に応じて避けて下さい。

途中でリカバリ・メソッドを選択するように求められます。本実行例ではプライマリ・インスタンスからセカンダリ・インスタンスへ最も簡単にデータ移行できる、Clone を選択します。出力は下のようになります。

Adding instance to the replicaset... * Performing validation checks

This instance reports its own address as 127.0.0.1:5556
127.0.0.1:5556: Instance configuration is suitable.

* Checking async replication topology…
* Checking connectivity and SSL configuration…
* Checking transaction state of the instance…

NOTE: The target instance ‘127.0.0.1:5556’ has not been pre-provisioned (GTID set is empty). The Shell is unable to decide whether replication can completely recover its state.
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely overwrite the state of ‘127.0.0.1:5556’ with a physical snapshot from an existing replicaset member. To use this method by default, set the ‘recoveryMethod’ option to ‘clone’.

WARNING: It should be safe to rely on replication to incrementally recover the state of the new instance if you are sure all updates ever executed in the replicaset were done with GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the replicaset or a subset of it. To use this method by default, set the ‘recoveryMethod’ option to ‘incremental’.


Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone): Clone
* Updating topology
Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish…
NOTE: 127.0.0.1:5556 is being cloned from 127.0.0.1:5555
** Stage DROP DATA: Completed
** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
* Clone process has finished: 166.11 MB transferred in about 1 second (~166.11 MB/s)
** Changing replication source of 127.0.0.1:5556 to 127.0.0.1:5555

** Waiting for new instance to synchronize with PRIMARY…
** Transactions replicated  ############################################################  100% 

The instance ‘127.0.0.1:5556’ was added to the replicaset and is replicating from 127.0.0.1:5555.

* Waiting for instance ‘127.0.0.1:5556’ to synchronize the Metadata updates with the PRIMARY…
** Transactions replicated  ############################################################  100%


出力されるメッセージにはレプリケーションの進行状況と、ポート5556のインスタンスがReplicaSetに追加され、ポート5556のインスタンスからレプリケーションが実行されていることが表示されます。

 

ステータスの確認

追加したセカンダリ・ノードに関する情報が、ReplicaSetステータスの表示にも追加されます。

rs.status()

ReplicaSetのステータスに先ほど追加したセカンダリ・インスタンスの情報が含まれます。

{
    "replicaSet": {
        "name": "demo_set",
        "primary": "127.0.0.1:5555",
        "status": "AVAILABLE",
        "statusText": "All instances available.",
        "topology": {
            "127.0.0.1:5555": {
                "address": "127.0.0.1:5555",
                "instanceRole": "PRIMARY",
                "mode": "R/W",
                "status": "ONLINE"
            },
            "127.0.0.1:5556": {
                "address": "127.0.0.1:5556",
                "instanceRole": "SECONDARY",
                "mode": "R/O",
                "replication": {
                    "applierStatus": "APPLIED_ALL",
                    "applierThreadState": "Waiting for an event from Coordinator",
                    "applierWorkerThreads": 4,
                    "receiverStatus": "ON",
                    "receiverThreadState": "Waiting for source to send event",
                    "replicationLag": null,
                    "replicationSsl": "TLS_AES_128_GCM_SHA256 TLSv1.3",
                    "replicationSslMode": "REQUIRED"
                },
                "status": "ONLINE"
            }
        },
        "type": "ASYNC"
    }
}

 

ReplicaSetの動作確認

ここまでの作業でReplicaSetが動いている状態なので、正しく動作していることを確認します。

 

セカンダリ・スキーマ

セカンダリ・インスタンス(ポート5556)の現在のスキーマを確認するには、MySQL Shellを使用してインスタンスに接続し、次のコマンドを実行します。

show schemas;

下記はこのコマンドの出力例です。

+-----------------------------------------------+
| Database                                   |
+-----------------------------------------------+
| information_schema                      |
| mysql                                       |
| mysql_innodb_cluster_metadata      |
| mysql_shorts                              |
| performance_schema                    |
| sys                                          |
+-----------------------------------------------+

 

ReplicaSet作成後に新しいスキーマが追加されたことが分かります。

  • mysql_shorts -プライマリ・インスタンスからコピーされたスキーマ
  • mysql_innodb_cluster_metadata – レプリケーションの管理に使用されるスキーマ
     

プライマリ・インスタンスに行追加

mysql_shortsスキーマのuserテーブルに行を挿入します。このテーブルには下記の4つの列があります。

  • id – テーブルのプライマリ・キー
  • first_name – ユーザーの名
  • last_name – ユーザーの姓
  • email – ユーザーのメール・アドレス

MySQL Shell を使用してプライマリ・インスタンス(ポート5555) に接続し、次のクエリを実行します。

insert into
    mysql_shorts.user(
    first_name,
    last_name,
    email
    )
values (
    'Skippy',
    'Dinglehoffer',
    'skip@dingle.com'
       );

次のクエリを実行して、行が正しく追加されていることを確認します。

select * from mysql_shorts.user order by id desc limit 5;

下記は出力例です。

+------+------------+--------------+---------------------------------------------+
| id   | first_name | last_name    | email                                 |
+------+------------+--------------+---------------------------------------------+
| 1001 | Skippy     | Dinglehoffer | skip@dingle.com                   |
| 1000 | Sharline   | Argile        | sargilerr@weather.com             |
|  999 | Gus        | Smerdon      | gsmerdonrq@csmonitor.com  |
|  998 | Matthias   | Lomen        | mlomenrp@seattletimes.com  |
|  997 | Liv        | Balsom       | lbalsomro@hostgator.com       |
+------+------------+--------------+---------------------------------------------+

先ほどプライマリ・インスタンスに追加した、Skippy Dinglehofferの行が表示されていることを確認します。

 

レプリカの確認

レプリケーションの動作確認には、MySQL Shellを使用してセカンダリ・インスタンス(ポート5556)に接続し、上記と同じクエリを実行します。

select * from mysql_shorts.user order by id desc limit 5;

出力結果がプライマリ・インスタンスで実行したものと一致するか確認します。

+------+------------+--------------+---------------------------------------------+
| id   | first_name | last_name    | email                                 |
+------+------------+--------------+---------------------------------------------+
| 1001 | Skippy     | Dinglehoffer | skip@dingle.com                   |
| 1000 | Sharline   | Argile        | sargilerr@weather.com             |
|  999 | Gus        | Smerdon      | gsmerdonrq@csmonitor.com  |
|  998 | Matthias   | Lomen        | mlomenrp@seattletimes.com  |
|  997 | Liv        | Balsom       | lbalsomro@hostgator.com       |
+------+------------+--------------+---------------------------------------------+

プライマリ・インスタンスに追加したユーザの行が、セカンダリ・インスタンスにも存在していれば、レプリケーションは正常に動作しています。

 

読み取り専用の確認

本記事でご紹介した手順でReplicaSetを作成すると、全てのセカンダリ・インスタンスが読み取り専用として動作します。つまり、セカンダリ インスタンスに直接データを挿入することはできません。

mysql_shorts.user テーブルにデータ行を挿入するクエリを、セカンダリ・インスタンスで実行することで確認します。

insert into
    mysql_shorts.user(
    first_name,
    last_name,
    email
    )
values (
    'Asmine',
    'Ono',
    'asmine@chikuwabu.com'
       );

実行すると下のように、セカンダリ・インスタンスが読み取り専用であることを知らせるメッセージが表示されます。

ERROR: 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement


まとめ

MySQL Shellを使用すると、InnoDB ReplicaSetを短時間で且つ簡単に作成できます。複数のコマンドを実行するだけで、InnoDB ReplicaSetの作成からセカンダリ・インスタンスの追加まで完了します。本記事ではInnoDB ReplicaSet作成の検証を、MySQL SandboxインスタンスとMySQL Shellを使用して行いました。InnoDB ReplicaSetについて詳しくは、公式Webマニュアルをご覧下さい。