CLOVER🍀

That was when it all began.

MySQL 8.0.21以降で、レプリケーションの用語が変わっていっている(Master → Source、Slave → Replica)という話

これは、なにをしたくて書いたもの?

世の中、"master"や"slave"という単語が違う表現に置き換えられていっていますが、そういえばMySQLの
レプリケーションでもこのあたりの単語を使っていましたがどうなったのかな?と思って見てみたら。

ちょっとずつ変わっていっているみたいなので、置き換えられた単語でレプリケーションを構成してみることに
しました。

あと、レプリケーションでの通信を非SSL/TLSで行う場合の認証でもちょっとハマったので、そちらもメモとして。

単語の変化

MySQL 8.0.21でドキュメントが、8.0.22以降で実際に使うシンタックスが変化していっているみたいです。

方針的には、"master"が"source"へ、"slave"が"replica"へ。
あとは"whitelist"が"allowlist"へ、"blacklist"が"blocklist"へ、という感じみたいですね。

In the documentation for MySQL 8.0.21, we have started changing the term “master” to “source”, the term “slave” to “replica”, the term “whitelist” to “allowlist”, and the term “blacklist” to “blocklist”. There are currently no changes to the product's syntax, so these terms are still present in the documentation where the current code requires their use. See the blog post MySQL Terminology Updates for more information.

MySQL :: MySQL 8.0 Release Notes :: Changes in MySQL 8.0.21 (2020-07-13, General Availability)

From MySQL 8.0.22, the statements START SLAVE, STOP SLAVE, SHOW SLAVE STATUS, SHOW SLAVE HOSTS and RESET SLAVE are deprecated. The following aliases should be used instead:

MySQL :: MySQL 8.0 Release Notes :: Changes in MySQL 8.0.22 (2020-10-19, General Availability)

From MySQL 8.0.23, the statement CHANGE MASTER TO is deprecated. The alias CHANGE REPLICATION SOURCE TO should be used instead. The parameters for the statement also have aliases that replace the term MASTER with the term SOURCE.

MySQL :: MySQL 8.0 Release Notes :: Changes in MySQL 8.0.23 (2021-01-18, General Availability)

Incompatible Change: From MySQL 8.0.26, new aliases or replacement names are provided for most remaining identifiers that contain the terms “master”, which is changed to “source”;

MySQL :: MySQL 8.0 Release Notes :: Changes in MySQL 8.0.26 (2021-07-20, General Availability)

レプリケーションに関するドキュメント

レプリケーションに関するドキュメントは、このあたりを参照します。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 17.1.3.4 GTID を使用したレプリケーションのセットアップ

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.4.1 ソースサーバーを制御する SQL ステートメント

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.4.2 レプリケーションサーバーを制御するための SQL ステートメント

GTIDを使ったレプリケーションで組むことにします。

環境

今回の環境は、こちらです。

MySQL。

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.27    |
+-----------+
1 row in set (0.00 sec)

MySQLサーバーは2台用意し、以下の役割とします。

  • Source … 172.17.0.2
  • Replica … 172.17.0.3

Sourceは以前で言うMaster、Replicaは以前で言うSlaveです。

Sourceのセットアップ

では、まずはSource側のセットアップから。

レプリケーションまわりで、必要な設定はこのあたり。

## gtid
gtid_mode = on
enforce_gtid_consistency = on

## binary log
log-bin = mysql-bin
sync_binlog = 1
binlog_expire_logs_seconds = 864000
binlog_checksum=NONE

## replication
server_id = 1

レプリケーション用のユーザーを作成。

mysql> create user repl@'%' identified by 'password';
Query OK, 0 rows affected (0.04 sec)

mysql> grant replication slave on *.* to 'repl'@'%';
Query OK, 0 rows affected (0.02 sec)

grant文に関しては、"slave"という単語がまだ残っているようです("replica"には置き換えられませんでした)。

GRANT ステートメント / MySQL によってサポートされる権限

これで、Sourceのセットアップは終わりです。

まあ、ここまでは単語の変化は見えませんね。

ちなみに、show master statusについても単語は変わっていないみたいです。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.7.7.23 SHOW MASTER STATUS ステートメント

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000002
         Position: 660
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: c39bd721-35b2-11ec-9fc4-0242ac110002:1-2
1 row in set (0.00 sec)

Replicaのセットアップ

続いて、Replicaを設定します。

MySQLの設定は、こちら。Sourceとはserver_idが異なり、それからread_onlyがonになっています。

## gtid
gtid_mode = on
enforce_gtid_consistency = on

## binary log
log-bin = mysql-bin
sync_binlog = 1
binlog_expire_logs_seconds = 864000
binlog_checksum=NONE

## replication
server_id = 2
read_only = on

レプリケーションでの通信にSSL/TLSを使う場合、change replication source to文を使ってSourceの情報を設定する際に、
source_sslを1にします。

mysql> change replication source to source_host = '172.17.0.2', source_port = 3306, source_ssl = 1, source_auto_position = 1;
Query OK, 0 rows affected (0.23 sec)

レプリケーションでの通信をSSL/TLS化しない場合は、Sourceに対して先ほど作成したレプリケーション用のユーザーで
接続し、--get-server-public-keyオプションを使ってRSA公開鍵を取得します。
※もしくは、レプリケーションの通信をSSL/TLSにします

$ mysql --ssl-mode=DISABLED -urepl -p -h172.17.0.2 --get-server-public-key
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.27 MySQL Community Server - GPL

Copyright (c) 2000, 2021, 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> exit
Bye

そして、change replication source to文でSourceの情報を設定します。

mysql> change replication source to source_host = '172.17.0.2', source_port = 3306, source_auto_position = 1;
Query OK, 0 rows affected (0.13 sec)

SSL/TLSを有効、無効のいずれかの方法でchange replication source to文を実行したら、start replica文で
レプリケーションを開始します。

mysql> start replica user = 'repl' password = 'password';
Query OK, 0 rows affected (0.04 sec)

レプリケーションのステータス確認。

mysql> show replica status\G
*************************** 1. row ***************************
             Replica_IO_State: Waiting for source to send event
                  Source_Host: 172.17.0.2
                  Source_User: repl
                  Source_Port: 3306
                Connect_Retry: 60
              Source_Log_File: mysql-bin.000002
          Read_Source_Log_Pos: 660
               Relay_Log_File: 6502f56a3e70-relay-bin.000002
                Relay_Log_Pos: 867
        Relay_Source_Log_File: mysql-bin.000002
           Replica_IO_Running: Yes
          Replica_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Source_Log_Pos: 660
              Relay_Log_Space: 1075
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Source_SSL_Allowed: Yes
           Source_SSL_CA_File: 
           Source_SSL_CA_Path: 
              Source_SSL_Cert: 
            Source_SSL_Cipher: 
               Source_SSL_Key: 
        Seconds_Behind_Source: 0
Source_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Source_Server_Id: 1
                  Source_UUID: c39bd721-35b2-11ec-9fc4-0242ac110002
             Source_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
    Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Source_Retry_Count: 86400
                  Source_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Source_SSL_Crl: 
           Source_SSL_Crlpath: 
           Retrieved_Gtid_Set: c39bd721-35b2-11ec-9fc4-0242ac110002:1-2
            Executed_Gtid_Set: c39bd721-35b2-11ec-9fc4-0242ac110002:1-2
                Auto_Position: 1
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Source_TLS_Version: 
       Source_public_key_path: 
        Get_Source_public_key: 0
            Network_Namespace: 
1 row in set (0.01 sec)

確認

最後に、レプリケーションが動作していることを確認します。

Sourceに接続して、データベースとユーザーを作成。

mysql> create database example;
Query OK, 1 row affected (0.03 sec)

mysql> create user kazuhira@localhost identified by 'password';
Query OK, 0 rows affected (0.03 sec)

mysql> create user kazuhira@'%' identified by 'password';
Query OK, 0 rows affected (0.02 sec)

mysql> grant all privileges on example.* to 'kazuhira'@localhost;
Query OK, 0 rows affected, 1 warning (0.02 sec)

Warning (Code 1285): MySQL is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work
mysql> grant all privileges on example.* to 'kazuhira'@'%';
Query OK, 0 rows affected (0.02 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

作成したユーザーで、Sourceにログインしてテーブル作成。

$ mysql -ukazuhira -p example
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.27 MySQL Community Server - GPL

Copyright (c) 2000, 2021, 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> create table t(c int);
Query OK, 0 rows affected (0.11 sec)

Replicaで確認してみます。

$ mysql -ukazuhira -p example
Enter password: 
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 8.0.27 MySQL Community Server - GPL

Copyright (c) 2000, 2021, 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 tables;
+-------------------+
| Tables_in_example |
+-------------------+
| t                 |
+-------------------+
1 row in set (0.00 sec)

OKですね。

Replica側は、Read Onlyです。

mysql> create table t2(c2 int);
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement

これで、確認できました、と。

RSA公開鍵の取得について

Replicaの構築している中で、RSA公開鍵の取得がありました。

これを飛ばすと、以下のようなエラーを見ることになります。非SSL/TLS接続での時に発生するみたいです。

2021-10-25T14:10:38.866725Z 15 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error connecting to master 'repl@172.17.0.2:3306' - retry-time: 60 retries: 1 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection. Error_code: MY-002061

これを回避するには、RSA公開鍵をサーバーから取得するか、1度サーバーにログインしてキャッシュを作成する
必要があるみたいです。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 6.4.1.2 SHA-2 プラガブル認証のキャッシュ

日々の覚書: MySQL 8.0のcaching_sha2_password + 非SSL接続が転ける

8.0の最初からこんな感じでしたっけ…?

今回、RSA公開鍵の取得をしない場合にsource_sslを1にする方法も書きましたが、これは通信の暗号化のみを
意味します。

レプリケーション接続用の SOURCE_SSL=1 | MASTER_SSL=1 を設定し、それ以上の SOURCE_SSL_xxx | MASTER_SSL_xxx オプションを設定しないことは、暗号化接続のコマンドオプション で説明されているように、クライアント用の --ssl-mode=REQUIRED の設定に対応します。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 17.3.1 暗号化接続を使用するためのレプリケーションの設定

--ssl-mode=VERIFY_CAや--ssl-mode=VERIFY_IDENTITY相当を行うにはもう少し設定が必要みたいですが、
そちらは今回はパスです…。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 6.3.1 暗号化接続を使用するための MySQL の構成