はじめに

みなさん、こんにちは。
Oracle Cloud Infrastructure 検証チームです。

今回は、OCIの入門編チュートリアルにもある
MySQL Database Serviceでリードレプリカを構成するを実際に検証し、
構築してみましたのでご紹介したいと思います。

以前にもチュートリアルにあるクラウドでMySQL Databaseを使うMySQLで高速分析を体験するクラウドでMySQL Databaseを高可用性構成で使うを検証した記事も投稿してますので、まだ見てないという方は先にそちらもご覧ください。

リードレプリカ とは

リードレプリカとは、
参照処理を負荷分散する目的で使用される参照専用の複製のことです。
参照処理の同時実行数が多いシステムでは、リードレプリカを使って負荷分散することが効果的です。

MDSのリードレプリカは非同期レプリケーションを使って構成されていますので、
リードレプリカから参照したデータは最新のデータでは無い可能性があることに注意が必要です。

リードレプリカへのアクセス方法は、以下2つの方法があります。
なお、ロードバランサーの設定は自動化されているため、
ユーザーがロードバランサーの存在や設定を意識する必要はありません。

  1. ロードバランサーを経由してアクセスする。
    この場合、接続先はリードレプリカ全体でロードバランスされる。
  2. リードレプリカ毎に設定されたエンドポイント(プライベートIPアドレス)を使用してアクセスする。
    この場合、それぞれのリードレプリカに直接接続する。

今回、構築検証するリードレプリカの構成図は以下のようになります。

作成してみた

前提として、今回使用するVCNとインスタンスは、すでに作成してあります。

今回の検証の流れは以下の通りです。

  1. MDSの作成
  2. リードレプリカの作成
  3. リードレプリカへの接続確認(ロードバランサー経由)
  4. リードレプリカへの接続確認(直接接続)
  5. リードレプリカの確認

MDSの作成

ソースとなるMDSを作成していきます。
MDSの作成につきましては以前紹介した
クラウドでMySQL Databaseを使うからの変更点のみ記載いたします。
詳細な手順は上記記事をご覧ください。

作成に入る前にリードレプリカの制限事項について下記に記載いたします。

リードレプリカの制限事項

  • ソースとなるMDSのOCPUが4OCPU以上必要
  • リードレプリカのスペックは、ソースとなるMDSのスペックと同一になる
    (リードレプリカだけスペックを落とす、といったことはまだできない)
  • リードレプリカの個数は最大18個まで
  • ロードバランサーからリードレプリカにアクセスするための帯域は最大8Gbps

今回注目してほしい部分はひとつ目に記載した4OCPU以上が必要な部分になります。
上記の変更を行なうための手順例を下記に記します。

  1. ハードウェアの構成部分のシェイプの変更をクリック

  2. 4OCPU以上のシェイプを選択
    以下のスクリーンショットは、CPUの種類がE4、CPU数が4OCPU、メモリーサイズが64GBのシェイプ(MySQL.VM.Standard.E4.4.64GB)を選択した例
  3. 想定通りのシェイプが選択されていることを確認

上記の通り変更することによってリードレプリカを使用することができます!

リードレプリカの作成

ロードバランサーを使用した負荷分散を試すため、今回はリードレプリカを2つ作成していきます。

  1. 先ほど作成したMDSをコンソールから選択し、
    画面左下のリソース → 読取りレプリカ をクリックします。

  2. 読取りレプリカの作成をクリックします。

  3. 名前に「ReadReplica1」と入力し、読取りレプリカの作成をクリックします。

  4. ReadReplica1の状態が作成中であることを確認します。
  5. ReadReplica1の状態がアクティブに変わったことを確認します。
    また、読取りレプリカのアクティブの数が「1」になっていることも確認します。

  6. 同様の手順で2つ目のリードレプリカを作成します。名前は「ReadReplica2」で作成します。

これでリードレプリカの作成が完了いたしました!

リードレプリカへの接続確認(ロードバランサー経由)

作成したリードレプリカへロードバランサー経由で接続してみましょう。

  1. MDSをコンソールから選択し、画面左下のリソース → エンドポイント をクリックします。

  2. 読取りレプリカ・ロード・バランサのIPアドレスを確認します。

  3. 確認した読取りレプリカ・ロード・バランサのIPアドレスを使用してリードレプリカに接続し、
    「SHOW GLOBAL VARIABLES LIKE ‘bind_address’」を実行します。
    [opc@testvm1 ~]$ mysql -u root -p -h 10.0.1.146
    Enter password:
    Welcome to the MySQL monitor. Commands end with ; or \g.
    Your MySQL connection id is 53
    Server version: 8.0.34-u3-cloud MySQL Enterprise - Cloud
    
    Copyright (c) 2000, 2023, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> SHOW GLOBAL VARIABLES LIKE 'bind_address';
    +---------------+-------------------------------------------+
    | Variable_name | Value                                     |
    +---------------+-------------------------------------------+
    | bind_address  | 10.0.1.248/mysql,10.5.62.19/loadbalancer  |
    +---------------+-------------------------------------------+
    1 row in set (0.00 sec)
    

    システム変数bind_addressの設定値に含まれるIPアドレスより、どちらのリードレプリカに接続しているかを判断できます。
    以下の実行例では、設定値に「10.0.1.248(ReadReplica1のIPアドレス)」が含まれているため、
    ReadReplica1に接続できていることが確認できます。(ReadReplica2に接続される場合もあります)

  4. ロードバランサー経由の接続では自動的にリードレプリカ間でロードバランスされることを確認します。
    前ステップの操作を繰り返し実行し、接続先が切り替わることを確認します。
    [opc@testvm1 ~]$ mysql -u root -p -h 10.0.1.146 -e "SHOW GLOBAL VARIABLES LIKE 'bind_address'"
    Enter password:
    +---------------+-------------------------------------------+
    | Variable_name | Value                                     |
    +---------------+-------------------------------------------+
    | bind_address  | 10.0.1.206/mysql,10.5.84.235/loadbalancer |
    +---------------+-------------------------------------------+
    [opc@testvm1 ~]$
    [opc@testvm1 ~]$ mysql -u root -p -h 10.0.1.146 -e "SHOW GLOBAL VARIABLES LIKE 'bind_address'"
    Enter password:
    +---------------+-------------------------------------------+
    | Variable_name | Value                                     |
    +---------------+-------------------------------------------+
    | bind_address  | 10.0.1.248/mysql,10.5.62.19/loadbalancer  |
    +---------------+-------------------------------------------+
    [opc@testvm1 ~]$
    [opc@testvm1 ~]$ mysql -u root -p -h 10.0.1.146 -e "SHOW GLOBAL VARIABLES LIKE 'bind_address'"
    Enter password:
    +---------------+-------------------------------------------+
    | Variable_name | Value                                     |
    +---------------+-------------------------------------------+
    | bind_address  | 10.0.1.206/mysql,10.5.84.235/loadbalancer |
    +---------------+-------------------------------------------+

    上記実行例では、mysqlコマンドラインクライアントの-eオプションを使用し、MDSへ接続して「SHOW GLOBAL VARIABLES LIKE ‘bind_address’」を実行することを繰り返し実行しています。
    接続によって「10.0.1.248(ReadReplica1のIPアドレス)」と「10.0.1.206(ReadReplica2のIPアドレス)」が切り替わっていることから、ロードバランスされていることが確認できます。

ロードバランサーによって正常に振り分けが実行されていることが確認できました!

リードレプリカへの接続確認(直接接続)

次は作成したリードレプリカへ直接接続してみましょう。

  1. MDSをコンソールから選択し、画面左下のリソース → エンドポイント をクリックします。

  2. ReadReplica1とReadReplica2のIPアドレスを確認します。
    2つのIPアドレスが異なるため、それぞれのIPアドレスを使用することで、
    任意のリードレプリカにアクセスできます。

  3. 確認したReadReplica1のIPアドレスを使用してリードレプリカに接続し
    「SHOW GLOBAL VARIABLES LIKE ‘bind_address’」を実行します。
    [opc@testvm1 ~]$ mysql -u root -p -h 10.0.1.248 -e "SHOW GLOBAL VARIABLES LIKE 'bind_address'"
    Enter password:
    +---------------+-------------------------------------------+
    | Variable_name | Value                                     |
    +---------------+-------------------------------------------+
    | bind_address  | 10.0.1.248/mysql,10.5.62.19/loadbalancer  |
    +---------------+-------------------------------------------+
    

    上記の実行例では、システム変数bind_addressの設定値に「10.0.1.206(ReadReplica1のIPアドレス)」が含まれているため、ReadReplica1に接続できていることが確認できます。

  4. 同様に、確認したReadReplica2のIPアドレスを使用してリードレプリカに接続し
    「SHOW GLOBAL VARIABLES LIKE ‘bind_address’」を実行します。
    [opc@testvm1 ~]$ mysql -u root -p -h 10.0.1.206 -e "SHOW GLOBAL VARIABLES LIKE 'bind_address'" 
    Enter password: 
    +---------------+-------------------------------------------+
    | Variable_name | Value                                     |
    +---------------+-------------------------------------------+
    | bind_address  | 10.0.1.206/mysql,10.5.84.235/loadbalancer |
    +---------------+-------------------------------------------+
    

    上記の実行例では、システム変数bind_addressの設定値に「10.0.1.206(ReadReplica2のIPアドレス)」が含まれているため、ReadReplica2に接続できていることが確認できます。

直接接続した際の動作も問題ないことが確認できました!

リードレプリカの確認

リードレプリカにソースのMDSが複製され、その後の更新処理も伝播されることを確認します。
また、リードレプリカは参照専用であることも確認します。

  1. ReadReplica1に接続後、「SHOW DATABASES」を実行します。
    [opc@testvm1 ~]$ mysql -u root -p -h 10.0.1.248
    Enter password: 
    Welcome to the MySQL monitor. Commands end with ; or \g.
    Your MySQL connection id is 178
    Server version: 8.4.0-cloud MySQL Enterprise - Cloud
    
    Copyright (c) 2000, 2024, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> SHOW DATABASES;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | mysql_audit        |
    | performance_schema |
    | sys                |
    | world              |
    | world_x            |
    +--------------------+
    7 rows in set (0.00 sec)
    

    worldデータベース、world_xデータベースが存在するため、
    リードレプリカ作成時点のWriterMDSが複製されていることが分かります。

  2. ソースのMDSで実行した更新処理がリードレプリカに反映されることを確認します。
    ソースのMDSでtestデータベース、test.testテーブルを作成し、データをINSERTします。
    その後、ReadReplica1でtest.testテーブルが存在することを確認し、INSERTされたデータがSELECTできることを確認します。実行例:ソースMDS
    mysql> CREATE DATABASE ReadReplica;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> CREATE TABLE ReadReplica.test(id int AUTO_INCREMENT, col1 CHAR(10), PRIMARY KEY(id));
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> INSERT INTO ReadReplica.test VALUES(1, "TEST");
    Query OK, 1 row affected (0.04 sec)
    
    mysql> SELECT * FROM ReadReplica.test;
    +----+------+
    | id | col1 |
    +----+------+
    |  1 | TEST |
    +----+------+
    1 row in set (0.00 sec)
    

    実行例:ReadReplica1

    mysql> SHOW DATABASES;    ※ソース側でcreateする前に実行
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | mysql_audit        |
    | performance_schema |
    | sys                |
    | world              |
    | world_x            |
    +--------------------+
    7 rows in set (0.00 sec)
    
    mysql> SHOW DATABASES;
    +--------------------+
    | Database           |
    +--------------------+
    | ReadReplica        |    ←ソース側で追加したReadReplicaが存在する
    | information_schema |
    | mysql              |
    | mysql_audit        |
    | performance_schema |
    | sys                |
    | world              |
    | world_x            |
    +--------------------+
    7 rows in set (0.00 sec)
    
    mysql> USE ReadReplica;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    
    mysql> SHOW TABLES;
    +-----------------------+
    | Tables_in_ReadReplica |
    +-----------------------+
    | test                  |
    +-----------------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT * FROM ReadReplica.test;
    +----+------+
    | id | col1 |
    +----+------+
    |  1 | TEST |
    +----+------+
    1 row in set (0.00 sec)
  3. リードレプリカが参照専用であることを確認します
    ReadReplica1でtest.testテーブルにデータをINSERTしようとするとエラーが発生すること。
    mysql> INSERT INTO ReadReplica.test VALUES(2, "READ ONLY");
    ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement

    システム変数「read_only」及び「super_read_only」を確認し、「ON」になっていること。

    mysql> SHOW GLOBAL VARIABLES LIKE '%read_only';
    +-----------------------+-------+
    | Variable_name         | Value |
    +-----------------------+-------+
    | innodb_read_only      |  OFF  |
    | read_only             |  ON   |
    | super_read_only       |  ON   |
    | transaction_read_only |  OFF  |
    +-----------------------+-------+
    4 rows in set (0.00 sec)

正常にソースMDSからの更新が反映されており、
設定も問題ないことが確認できました!

おわりに

今回は、OCIの入門編チュートリアルにある、MySQL Database Serviceでリードレプリカを構成する を実際に検証し、作成してみました。

いかかでしたでしょうか。

リードレプリカ自体の作成はとても簡単で、
参照処理の多いシステムなどで使用すればサーバーへの負荷の軽減が見込めるのでとてもおススメな機能です!

最後までご覧いただきありがとうございました!

Oracle Cloudをご検討の際は当社までお気軽にお問い合わせください。

投稿者プロフィール

技術チーム
技術チーム
DBひとりでできるもんを盛り上げるべく、技術チームが立ち上がり早6年。ひとりでできるもんと言いつつ、技術者が読んでプッとなるような、極めてピンポイントでマニアックな技術ネタを執筆しています!