2025年7月3日木曜日

MySQL8.4でレプリケーション構成を試してみた

MySQL8.4でレプリケーション構成を試してみた

概要

検証なので docker 上で構築しています
パラメータなどはそのまま使えると思います

8.4 から Master/Slave は Source/Replica となりコマンドを完全に変わっているので注意しましょう

環境

  • Ubuntu 24.04
  • docker 28.2.2
  • MySQL 8.4.5

compose.yaml

基本的には Source/Replica に必要な設定を指定して起動するだけです
mysql-native-password に関しては後述しますが指定不要にもできます

healthcheck はいらないかもです

services:
  mysql-master:
    image: mysql:8.4.5
    container_name: mysql-master
    environment:
      - MYSQL_ROOT_PASSWORD=rootpassword
    command:
      - --mysql-native-password=ON
      - --server-id=1
      - --log-bin=mysql-bin
      - --gtid-mode=ON
      - --enforce-gtid-consistency=ON
    ports:
      - "3306:3306"
    volumes:
      - master_data:/var/lib/mysql
      - ./master-init/:/docker-entrypoint-initdb.d/
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: always

  mysql-slave:
    image: mysql:8.4.5
    container_name: mysql-slave
    depends_on:
      - mysql-master
    environment:
      - MYSQL_ROOT_PASSWORD=rootpassword
    command:
      - --mysql-native-password=ON
      - --server-id=2
      - --log-bin=mysql-bin
      - --gtid-mode=ON
      - --enforce-gtid-consistency=ON
      - --relay-log=relay-log
      - --read-only=ON
    ports:
      - "3307:3306"
    volumes:
      - slave_data:/var/lib/mysql
      - ./slave-init/:/docker-entrypoint-initdb.d/
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: always

volumes:
  master_data:
  slave_data:

./master-init/init-master.sql

公式の MySQL8.4.5 のイメージでは MYSQL_REPLICATION_USERMYSQL_REPLICATION_PASSWORD の環境変数は使えないので初期化スクリプトでレプリケーション用のユーザを作成します

CREATE USER 'replicator'@'%' IDENTIFIED BY 'replicatorpassword';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

./slave-init/init-replica.sql

スレーブ側ではマスターに接続する設定を初期化スクリプトで行います
MASTER_HOST などは使えず SOURCE_HOST になっているので注意しましょう

CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='mysql-master',
  SOURCE_USER='replicator',
  SOURCE_PASSWORD='replicatorpassword',
  SOURCE_AUTO_POSITION=1;
START REPLICA;

動作確認

  • docker compose up -d

であとは Source/Replica の状態を確認します

Source (マスター)

mysql -h 127.0.0.1 -P 3306 -u root -p

mysql>  SHOW BINARY LOG STATUS\G
*************************** 1. row ***************************
             File: mysql-bin.000003
         Position: 198
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set: 705ee183-57b5-11f0-b5ae-2a2407db9148:1-8
1 row in set (0.00 sec)

Replica (スレーブ)

mysql> SHOW REPLICA STATUS\G
*************************** 1. row ***************************
             Replica_IO_State: Waiting for source to send event
                  Source_Host: mysql-master
                  Source_User: replicator
                  Source_Port: 3306
                Connect_Retry: 60
              Source_Log_File: mysql-bin.000003
          Read_Source_Log_Pos: 198
               Relay_Log_File: relay-log.000004
                Relay_Log_Pos: 415
        Relay_Source_Log_File: mysql-bin.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: 198
              Relay_Log_Space: 2985967
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Source_SSL_Allowed: No
           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: 705ee183-57b5-11f0-b5ae-2a2407db9148
             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: 705ee183-57b5-11f0-b5ae-2a2407db9148:1-8
            Executed_Gtid_Set: 705ee183-57b5-11f0-b5ae-2a2407db9148:1-8,
708f9d45-57b5-11f0-b04a-d263a8c2e257:1-5
                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.00 sec)

あとはデータベースやテーブルを作成して Replica 側でデータがあることを確認しましょう

mysql_native_password を使わないほうがいい

sha256_password も deprecated なので caching_sha2_password を使いましょう

基本的には起動オプションを変更してレプリケーション用のユーザのパスワードを設定する際に caching_sha2_password を使えば OK です

  • vim compose.yaml
services:
  mysql-master:
    image: mysql:8.4.5
    container_name: mysql-master
    environment:
      - MYSQL_ROOT_PASSWORD=rootpassword
    command:
      - --server-id=1
      - --log-bin=mysql-bin
      - --gtid-mode=ON
      - --enforce-gtid-consistency=ON
    ports:
      - "3306:3306"
    volumes:
      - master_data:/var/lib/mysql
      - ./master-init/:/docker-entrypoint-initdb.d/
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: always

  mysql-slave:
    image: mysql:8.4.5
    container_name: mysql-slave
    depends_on:
      - mysql-master
    environment:
      - MYSQL_ROOT_PASSWORD=rootpassword
    command:
      - --server-id=2
      - --log-bin=mysql-bin
      - --gtid-mode=ON
      - --enforce-gtid-consistency=ON
      - --relay-log=relay-log
      - --read-only=ON
    ports:
      - "3307:3306"
    volumes:
      - slave_data:/var/lib/mysql
      - ./slave-init/:/docker-entrypoint-initdb.d/
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: always

volumes:
  master_data:
  slave_data:
  • vim ./master-init/init-master.sql
CREATE USER 'replicator'@'%'
IDENTIFIED WITH caching_sha2_password BY 'replicatorpassword';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

最後に

MySQL8.4.5 で Source/Replica 構成を構築してみました
構築自体は非常に簡単にできます
MySQL8.4.5で非推奨になっていたり使えないコマンドが増えているのでそこは注意しましょう

参考サイト

0 件のコメント:

コメントを投稿