CLOVER🍀

That was when it all began.

MySQL 8.4でGTIDレプリケヌションを構成する

これは、なにをしたくお曞いたもの

MySQL 8.4になっおからレプリケヌションを行う環境を䜜ったこずがなかったので、蚭定しおおこうずいうこずで。

MySQLのレプリケヌション

MySQL 8.4のレプリケヌションに関するドキュメントはこちら。

MySQL :: MySQL 8.4 Reference Manual :: 19 Replication

MySQLのレプリケヌションには、バむナリヌログのポゞションにもずづくものず、
Global Transaction IdentifiersGTIDを䜿ったものの2皮類がありたす。

今回はGTIDを䜿ったレプリケヌションで構成したす。

レプリケヌションの蚭定方法はこちら。

MySQL :: MySQL 8.4 Reference Manual :: 19.1.3.4 Setting Up Replication Using GTIDs

レプリケヌションに関するSQLはこちら。

MySQL :: MySQL 8.4 Reference Manual :: 15.4 Replication Statements

このあたりは実際にレプリケヌションを構成する時に出おきたすが、ここではGTIDを䜿ったレプリケヌションでの
制限事項を芋おおきたす。

MySQL :: MySQL 8.4 Reference Manual :: 19.1.3.7 Restrictions on Replication with GTIDs

GTIDを䜿ったレプリケヌションでは、以䞋の制限があるずされおいたす。

  • 非トランザクショナルなストレヌゞ゚ンゞンのテヌブルの曎新ず、トランザクショナルなストレヌゞ゚ンゞンのテヌブルの曎新を同じステヌトメントたたはトランザクションで行えない
  • アトミックDDLをサポヌトするストレヌゞ゚ンゞンInnoDBの堎合、CREATE TABLE ... SELECTはひず぀のトランザクションずしおバむナリヌログに蚘録される
  • binlog_formatがSTATEMENTに蚭定されおいお、サヌバヌ䞊でGTIDを䜿甚しおいる堎合、トランザクション内でCREATE TEMPORARY TABLEおよびDROP TEMPORARY TABLEの䜿甚䞍可
  • サポヌトされおいないSQLの実行を゚ラヌで倱敗させる
  • sql_replica_skip_counterを䜿甚したむベント数を指定したスキップの䞍可
  • IGNORE_SERVER_IDSの䜿甚䞍可

アトミックDDLずはずいう気になりたしたが、デヌタディクショナリヌの曎新、ストレヌゞ゚ンゞンの操䜜、
バむナリヌログの操䜜を単䞀のアトミック操䜜ずするDDLのこずらしいです。

MySQL :: MySQL 8.4 Reference Manual :: 15.1.1 Atomic Data Definition Statement Support

たた、アトミックDDLはトランザクションDDLではないため、䜿甚するずその時点でアクティブなトランザクションが
あるず暗黙的にコミットしたす。

芋おみるず、よく䜿うようなDDLはアトミックDDLのようですね 。

第93回 MySQL8.0のデータディクショナリー | gihyo.jp

DDLの実行途䞭で䞭断したりした堎合に、䞭途半端な状態にならないようにする仕組みのようです。

それではドキュメントを芋るのはこれくらいにしお、実際にGTIDを䜿ったレプリケヌションを構築しおみたしょう。

環境

今回の環境はこちら。2぀のUbuntu Linux 24.04 LTSのサヌバヌを甚意したす。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04.2 LTS
Release:        24.04
Codename:       noble


$ uname -srvmpio
Linux 6.8.0-57-generic #59-Ubuntu SMP PREEMPT_DYNAMIC Sat Mar 15 17:40:59 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

IPアドレスはそれぞれ192.168.33.10、192.168.33.11ずしたす。

192.168.33.10はSource、192.168.33.11はReplicaにするこずにしたす。

MySQLをむンストヌルする

ひずたずMySQLをむンストヌルしたしょう。

$ curl -LO https://dev.mysql.com/get/mysql-apt-config_0.8.33-1_all.deb
$ sudo dpkg -i mysql-apt-config_0.8.33-1_all.deb
$ sudo apt update
$ sudo apt install mysql-server

操䜜はMySQL Shellから行うこずにしたす。

$ sudo apt install mysql-shell

今回はMySQL 8.4.4がむンストヌルされたした。

$ mysqlsh --version
mysqlsh   Ver 8.4.4 for Linux on x86_64 - for MySQL 8.4.4 (MySQL Community Server (GPL))


$ mysqlsh root@localhost

 MySQL  localhost:33060+ ssl  SQL > select version();
+-----------+
| version() |
+-----------+
| 8.4.4     |
+-----------+
1 row in set (0.0008 sec)

GTIDレプリケヌションを構成する

では、レプリケヌションを構成しおいきたしょう。

最初にMySQLサヌバヌは、2぀ずも停止しおおきたす。

$ sudo systemctl stop mysql

MySQLの蚭定を倉曎したす。デフォルトの蚭定はこんな感じです。

$ grep -v '#' /etc/mysql/mysql.conf.d/mysqld.cnf


[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
log-error       = /var/log/mysql/error.log
Sourceのセットアップ

Sourceの蚭定はこのようにしたした。

[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
log-error       = /var/log/mysql/error.log

character_set_server  = utf8mb4
collation_server      = utf8mb4_0900_bin
transaction_isolation = READ-COMMITTED

gtid_mode = on
enforce_gtid_consistency = on

log_bin = binlog
sync_binlog = 1
binlog_expire_logs_seconds = 864000

server_id = 1

ちなみに、この郚分はレプリケヌションに関係ありたせん。

character_set_server  = utf8mb4
collation_server      = utf8mb4_0900_bin
transaction_isolation = READ-COMMITTED

たたbinlog_expire_logs_secondsを蚭定したのはなんずなくです。

MySQLを起動。

$ sudo systemctl start mysql

レプリケヌション甚のナヌザヌを䜜成。

$ mysqlsh root@localhost
 MySQL  localhost:33060+ ssl  SQL > create user repl_user@'%' identified by 'password';
Query OK, 0 rows affected (0.0633 sec)


 MySQL  localhost:33060+ ssl  SQL > grant replication slave on *.* to 'repl_user'@'%';
Query OK, 0 rows affected (0.0179 sec)

暩限に぀いおは、未だに"slave"のようです。

バむナリヌログの確認。

 MySQL  localhost:33060+ ssl  SQL > show binary log status\G
*************************** 1. row ***************************
             File: binlog.000003
         Position: 700
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set: c6a5cdba-17a7-11f0-aaeb-525400d48b63:1-2
1 row in set (0.0014 sec)

これでSourceのセットアップは完了です。

Replicaのセットアップ

続いおはReplicaのセットアップです。

[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
log-error       = /var/log/mysql/error.log

character_set_server  = utf8mb4
collation_server      = utf8mb4_0900_bin
transaction_isolation = READ-COMMITTED

gtid_mode = on
enforce_gtid_consistency = on

log_bin = binlog
sync_binlog = 1
binlog_expire_logs_seconds = 864000

server_id = 2
read_only = on
relay_log = relay-binlog

Sourceずの違いはserver_idの倀ず、read_onlyですね。

MySQLを起動。

$ sudo systemctl start mysql

MySQLに接続したす。

$ mysqlsh root@localhost

レプリケヌションの蚭定。

 MySQL  localhost:33060+ ssl  SQL > change replication source to source_host = '192.168.33.10', source_port = 3306, source_auto_position = 1, source_ssl = 1;
Query OK, 0 rows affected (0.0593 sec)

MySQL :: MySQL 8.4 Reference Manual :: 15.4.2.2 CHANGE REPLICATION SOURCE TO Statement

この時点ではレプリケヌションは動䜜しおいたせん。

 MySQL  localhost:33060+ ssl  SQL > show replica status\G
*************************** 1. row ***************************
             Replica_IO_State:
                  Source_Host: 192.168.33.10
                  Source_User:
                  Source_Port: 3306
                Connect_Retry: 60
              Source_Log_File:
          Read_Source_Log_Pos: 4
               Relay_Log_File: relay-binlog.000001
                Relay_Log_Pos: 4
        Relay_Source_Log_File:
           Replica_IO_Running: No
          Replica_SQL_Running: No
              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: 0
              Relay_Log_Space: 158
              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: NULL
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: 0
                  Source_UUID:
             Source_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
    Replica_SQL_Running_State:
           Source_Retry_Count: 10
                  Source_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Source_SSL_Crl:
           Source_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                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.0020 sec)

Replicaの開始。

 MySQL  localhost:33060+ ssl  SQL > start replica user = 'repl_user' password = 'password';
Query OK, 0 rows affected, 1 warning (0.1097 sec)
Note (code 1759): Sending passwords in plain text without SSL/TLS is extremely insecure.

MySQL :: MySQL 8.4 Reference Manual :: 15.4.2.4 START REPLICA Statement

ドキュメントのようにchange replication source to 〜にナヌザヌ名ずパスワヌドを含めるず、以䞋のように
start replicaに含めるように譊告されるのですが。

Note (code 1760): Storing MySQL user name or password information in the connection metadata repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START REPLICA; see the 'START REPLICA Syntax' in the MySQL Manual for more information.

start replicaに入れたら入れたで、やっぱり譊告されるのですが 。

Note (code 1759): Sending passwords in plain text without SSL/TLS is extremely insecure.

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

 MySQL  localhost:33060+ ssl  SQL > show replica status\G
*************************** 1. row ***************************
             Replica_IO_State: Waiting for source to send event
                  Source_Host: 192.168.33.10
                  Source_User: repl_user
                  Source_Port: 3306
                Connect_Retry: 60
              Source_Log_File: binlog.000003
          Read_Source_Log_Pos: 700
               Relay_Log_File: relay-binlog.000002
                Relay_Log_Pos: 911
        Relay_Source_Log_File: binlog.000003
           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: 700
              Relay_Log_Space: 1119
              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: c6a5cdba-17a7-11f0-aaeb-525400d48b63
             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: 10
                  Source_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Source_SSL_Crl:
           Source_SSL_Crlpath:
           Retrieved_Gtid_Set: c6a5cdba-17a7-11f0-aaeb-525400d48b63:1-2
            Executed_Gtid_Set: c6a5cdba-17a7-11f0-aaeb-525400d48b63: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.0017 sec)

レプリケヌションが開始されたようです。

確認

最埌に動䜜確認。

Sourceに接続しお、デヌタベヌス、ナヌザヌを䜜成。

$ mysqlsh root@localhost


 MySQL  localhost:33060+ ssl  SQL > create database example;
Query OK, 1 row affected (0.0318 sec)


 MySQL  localhost:33060+ ssl  SQL > create user kazuhira@'%' identified by 'password';
Query OK, 0 rows affected (0.0490 sec)


 MySQL  localhost:33060+ ssl  SQL > grant all privileges on example.* to 'kazuhira'@'%';
Query OK, 0 rows affected (0.0252 sec)


 MySQL  localhost:33060+ ssl  SQL > flush privileges;
Query OK, 0 rows affected (0.0149 sec)

䜜成したナヌザヌで接続しなおし。

$ mysqlsh kazuhira@localhost/example

テヌブルずデヌタの䜜成。

 MySQL  localhost:33060+ ssl  example  SQL > create table t1(c1 varchar(20));
Query OK, 0 rows affected (0.1023 sec)


 MySQL  localhost:33060+ ssl  example  SQL > insert into t1(c1) values('foo');
Query OK, 1 row affected (0.0328 sec)


 MySQL  localhost:33060+ ssl  example  SQL > insert into t1(c1) values('bar');
Query OK, 1 row affected (0.0218 sec)


 MySQL  localhost:33060+ ssl  example  SQL > select * from t1;
+-----+
| c1  |
+-----+
| foo |
| bar |
+-----+
2 rows in set (0.0015 sec)

Replicaに接続。

$ mysqlsh kazuhira@localhost/example

デヌタがレプリケヌションされおいるこずが確認できたす。

 MySQL  localhost:33060+ ssl  example  SQL > select * from t1;
+-----+
| c1  |
+-----+
| foo |
| bar |
+-----+
2 rows in set (0.0019 sec)

なお、ReplicaはRead Onlyです。

 MySQL  localhost:33060+ ssl  example  SQL > create table t2(c2 varchar(20));
ERROR: 1290: The MySQL server is running with the --read-only option so it cannot execute this statement

これで確認できたした。

おわりに

MySQL 8.4でGTIDレプリケヌションの蚭定をしおみたした。

8.0の時ず倉わっおいたせんでしたが、時々こういうのを確認しないずな、ず思いたす。