GA

2025/04/16

HeatWave MySQLがどれくらいVanilla MySQL GPL版と同じくらいか考える旅 / 読み取りレプリカ編

WEB画面から作るレプリケーションの話。

「読み取りレプリカ」を “MySQL.8.Standalone” で1つ追加

ソースから観測

ソースから見ると名前解決が有効になってるのでIPアドレスはわからない。
skip_name_resolve はOFFで変えられない。

mysql> SHOW PROCESSLIST;
..
*************************** 4. row ***************************
     Id: 81
   User: ocirpl
   Host: gh7wpmau16ovyk9e.db0vcn0.mysqlcdbnrt.oraclevcn.com:52048
     db: NULL
Command: Binlog Dump GTID
   Time: 107046
  State: Source has sent all binlog to replica; waiting for more updates
   Info: NULL

..

mysql> SHOW REPLICAS;
+------------+------+------+------------+--------------------------------------+
| Server_Id  | Host | Port | Source_Id  | Replica_UUID                         |
+------------+------+------+------------+--------------------------------------+
| 1488978482 |      | 3306 | 3041463983 | 2ce0e2cf-18fb-11f0-bca9-02001704799d |
+------------+------+------+------------+--------------------------------------+
1 row in set (0.00 sec)

権限的には

あたり。

mysql> SHOW GRANTS FOR ocirpl;
+-------------------------------------------------------------------------------------------------------------+
| Grants for ocirpl@%                                                                                         |
+-------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO `ocirpl`@`%`                                                              |
| GRANT CONNECTION_ADMIN,GROUP_REPLICATION_STREAM,SERVICE_CONNECTION_ADMIN,SYSTEM_USER ON *.* TO `ocirpl`@`%` |
+-------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> ALTER USER ocirpl IDENTIFIED BY 'a' RETAIN CURRENT PASSWORD;
ERROR 1227 (42000): Access denied; you need (at least one of) the SYSTEM_USER privilege(s) for this operation

レプリカ側には「ホスト」に属しそうなIPと「ホスト群」に属しそうなIPが払い出されているぽい。

1台しか作ってないのでどっちを使っても同じところにアクセス。

$ for n in {1..100} ; do mysql -h 10.0.0.118 -uadmin -sse "SELECT @@hostname" ;  done | sort | uniq -c
    100 fuis3dpz4ueksuzu

$ for n in {1..100} ; do mysql -h 10.0.0.70 -uadmin -sse "SELECT @@hostname" ;  done | sort | uniq -c
    100 fuis3dpz4ueksuzu

ところで、100回程度でも気が付くくらいには差があった。LB経由の方が若干遅い。

$ time for n in {1..100} ; do mysql -h 10.0.0.118 -uadmin -sse "SELECT @@hostname" ;  done | sort | uniq -c
    100 fuis3dpz4ueksuzu

real    0m2.369s
user    0m1.040s
sys     0m0.489s

$ time for n in {1..100} ; do mysql -h 10.0.0.70 -uadmin -sse "SELECT @@hostname" ;  done | sort | uniq -c
    100 fuis3dpz4ueksuzu

real    0m1.708s
user    0m1.030s
sys     0m0.495s

レプリカから観測

大きめのシェイプじゃないとそもそもレプリカを作れないようになっている関係(?)で replica_parallel_workers はやたら多い。

mysql> SELECT @@replica_parallel_workers;
+----------------------------+
| @@replica_parallel_workers |
+----------------------------+
|                         48 |
+----------------------------+
1 row in set (0.00 sec)

mysql> SELECT name, processlist_user, processlist_host, COUNT(*) FROM performance_schema.threads WHERE type <> 'BACKGROUPND' GROUP BY 1, 2, 3;

..
| thread/sql/replica_io                                    | ociadmin         | localhost                                                 |        1 |
| thread/sql/replica_sql                                   | ociadmin         | localhost                                                 |        1 |
| thread/sql/replica_worker                                | ociadmin         | localhost                                                 |       48 |

..

performance_schema.threads は ociadmin なのに SHOW REPLICA STATUS は ocirpl なのはなんでかと思ったけど、 p_s.threads は単に START REPLICA した時のアカウントが出るっぽい。知らなかった。

mysql> SHOW REPLICA STATUS\G
*************************** 1. row ***************************
             Replica_IO_State: Waiting for source to send event
                  Source_Host: 10.0.114.60
                  Source_User: ocirpl
                  Source_Port: 7306
                Connect_Retry: 60
              Source_Log_File: binary-log.020772
          Read_Source_Log_Pos: 198
               Relay_Log_File: relay-log-oci_managed_read_replica.000306
                Relay_Log_Pos: 377
        Relay_Source_Log_File: binary-log.020772
           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: 198
              Relay_Log_Space: 655
              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: 3041463983
                  Source_UUID: 07c65c46-18f9-11f0-89e5-020017067068
             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: 0
                  Source_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Source_SSL_Crl:
           Source_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set: 9330ac0f-e14a-11ef-a07c-0200170681c1:1-853240
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name: oci_managed_read_replica
           Source_TLS_Version: TLSv1.2,TLSv1.3
       Source_public_key_path:
        Get_Source_public_key: 1
            Network_Namespace:
1 row in set (0.00 sec)

チャンネル名が指定されてたり、ポートが7306になったりしている。
これは admin_port 使ってるんだろうと思うんだけど

mysql> SELECT @@admin_address, @@admin_port;
+-----------------+--------------+
| @@admin_address | @@admin_port |
+-----------------+--------------+
| 127.0.0.1       |         7306 |
+-----------------+--------------+
1 row in set (0.00 sec)

なので、admin_portにアクセスできるのは本来自分自身にしかアクセスできないはず。
ぱっと思いつくのは 127.0.0.1:7306 は mysqld がLISTENして、 10.0.114.60:7306 は (ソースと同じノードに入った) mysqlrouter なりがLISTENして転送してればそうできるかなあと思ったりした。

なおこの 10.0.114.60 (レプリカから見たレプリケーションソースのアドレス) はクライアントからはアクセスできなかった。

mysql> SELECT * FROM mysql.slave_master_info\G
*************************** 1. row ***************************
                Number_of_lines: 33
                Master_log_name:
                 Master_log_pos: 4
                           Host: 10.0.114.60
                      User_name:
                  User_password:
                           Port: 7306
                  Connect_retry: 60
                    Enabled_ssl: 1
                         Ssl_ca:
                     Ssl_capath:
                       Ssl_cert:
                     Ssl_cipher:
                        Ssl_key:
         Ssl_verify_server_cert: 0
                      Heartbeat: 30
                           Bind:
             Ignored_server_ids: 0
                           Uuid:
                    Retry_count: 0
                        Ssl_crl:
                    Ssl_crlpath:
          Enabled_auto_position: 1
                   Channel_name: oci_managed_read_replica
                    Tls_version: TLSv1.2,TLSv1.3
                Public_key_path:
                 Get_public_key: 1
              Network_namespace:
   Master_compression_algorithm: uncompressed
  Master_zstd_compression_level: 3
               Tls_ciphersuites: NULL
Source_connection_auto_failover: 0
                      Gtid_only: 1
1 row in set (0.00 sec)

パスワードが平文で書かれることで(俺の中では)有名な mysql.slave_master_info にはユーザー情報はない。これは CHANGE REPLICATION SOURCE TO source_user = ?, source_password = ? でアカウントを設定せずに START REPLICA USER=? PASSWORD=? で START REPLICA ごとに指定するとこうなるのでそれを使ってる。

確かに自動化されてて人間が START REPLICA を打つことがない今日日のケースではそれは正しい気がする。

mysql> SELECT * FROM mysql.slave_relay_log_info\G
*************************** 1. row ***************************
                             Number_of_lines: 14
                              Relay_log_name: /db/replication/relay-log-oci_managed_read_replica.000001
                               Relay_log_pos: 4
                             Master_log_name:
                              Master_log_pos: 0
                                   Sql_delay: 0
                           Number_of_workers: 0
                                          Id: 1
                                Channel_name: oci_managed_read_replica
                   Privilege_checks_username: NULL
                   Privilege_checks_hostname: NULL
                          Require_row_format: 1
             Require_table_primary_key_check: OFF
 Assign_gtids_to_anonymous_transactions_type: OFF
Assign_gtids_to_anonymous_transactions_value:
1 row in set (0.00 sec)

mysql.slave_relay_log_info には特に面白い情報はない。 REPLICATION_APPLIER 権限を使った分離はされてないってことくらいか。

mysql> SHOW BINARY LOGS;
ERROR 1381 (HY000): You are not using binary logging

レプリカではバイナリログが有効になっていないので、バイナリログを吸い上げるツールをソースに向けたくなくてレプリカ……というわけにはいかなさそう。

取り敢えずこんなところで。

0 件のコメント :

コメントを投稿