Docker容器化部署MySQL主从集群(CentOS9+MySQL9)

准备

  • CentOS安装 可以虚拟机安装,目前最新版本CentOS9
  • docker安装 yum install docker-ce (或者 dnf install docker-ce CentOS9以后包管理工具使用dnf)
  • MySQL镜像拉取 docker pull mysql

1、 MySQL主从复制集群部署

1.1 主节点:

主节点部署

bash 复制代码
$ sudo docker run -p 3307:3306 \
 --name mysql-master \
 # 日志目录挂载
 -v /opt/mysqlmscluster/master/log:/var/log/mysql \
 # 数据文件目录挂载
 -v /opt/mysqlmscluster/master/data:/var/lib/mysql \
 # 配置目录挂载
 -v /opt/mysqlmscluster/master/conf:/etc/mysql/conf.d \
 # root密码设置
 -e MYSQL_ROOT_PASSWORD=root \
 -d mysql

容器启动

bash 复制代码
 $ sudo docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED        STATUS             PORTS                                                                        NAMES
c009495dbc75   mysql          "docker-entrypoint.s..."   7 hours ago    Up 2 hours         33060/tcp, 0.0.0.0:3307->3306/tcp, [::]:3307->3306/tcp                       mysql-master

主节点配置文件:

bash 复制代码
$ vim /opt/mysqlmscluster/master/conf/my.cnf
[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-name-resolve


#Server的实例ID,必须全局唯一
server_id=1

# 开启binlog
log-bin=mysql-bin
#是否只读,主节点可以读写
read-only=0
#需要记录binlog的数据库
binlog-do-db=shibing_test
#忽略的数据库
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema

重启主节点:

设置好配置文件后重启主节点:

bash 复制代码
$ sudo docker restart mysql-master

连接到主节点:

bash 复制代码
$ mysql -h 10.211.55.5 -uroot -proot -P3307
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 9.0.1 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>

创建用户backup,只有relication slave权限,用于从节点做主从同步数据

关于下面的两条命令,请查阅官方文档

bash 复制代码
MySQL [(none)]> create user 'backup'@'%' identified by '123456';
Query OK, 0 rows affected, 2 warnings (0.018 sec)

MySQL [(none)]> grant replication slave on *.* to 'backup'@'%';
Query OK, 0 rows affected, 2 warnings (0.018 sec)

MySQL [(none)]> flush privileges;

查看主节点状态:

这里注意在8.0以前的版本是show master status,后续版本改成了show binary log status;自8.0版本后master 和slave参数都有变化,slave基本上改成了replica。(这里不得不吐槽一下,改了很多很不方便,都是欧美种族歧视问题闹得)

bash 复制代码
MySQL [(none)]> SHOW BINARY LOG STATUS\G
*************************** 1. row ***************************
File: mysql-bin.000004
Position: 367
Binlog_Do_DB: shibing_test
Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.001 sec)

在主节点创建数据库并创建表:

bash 复制代码
MySQL [shibing_test]> create database shibing_test;
MySQL [shibing_test]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| shibing_test       |
| sys                |
+--------------------+
5 rows in set (0.002 sec)

MySQL [shibing_test]> CREATE TABLE IF NOT EXISTS `example_table` (
    ->   `id` INT NOT NULL AUTO_INCREMENT,
    ->   `name` VARCHAR(255) NOT NULL,
    ->   `email` VARCHAR(255) NOT NULL,
    ->   `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    ->   PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.022 sec)

MySQL [shibing_test]> show tables;
+------------------------+
| Tables_in_shibing_test |
+------------------------+
| example_table          |
+------------------------+
1 row in set (0.006 sec)

1.2 从节点:

从节点部署:

bash 复制代码
$ sudo docker run -d -p 3308:3306 \
 --name mysql-replica \
 -v /opt/mysqlmscluster/replica/log:/var/log/mysql \
 -v /opt/mysqlmscluster/replica/data:/var/lib/mysql \
 -v /opt/mysqlmscluster/replica/conf:/etc/mysql \
 -e MYSQL_ROOT_PASSWORD=root \
# 关联主节点
 --link mysql-master:mysql-master \
 mysql
 
 
 #从节点容器启动
 $ sudo docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED        STATUS             PORTS                                                                        NAMES
fd9ecf27cfbc   mysql          "docker-entrypoint.s..."   6 hours ago    Up About an hour   33060/tcp, 0.0.0.0:3308->3306/tcp, [::]:3308->3306/tcp                       mysql-replica

从节点配置:

bash 复制代码
$ vim /opt/mysqlmscluster/replica/conf/my.cnf
[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-name-resolve

server_id=2
# 这里从节点没有他自己的从节点(A->B->C这样的关系,B是A的从节点,同时是C的主节点),可以不开启binlog
log-bin=mysql-bin
# 从节点设为只读
read-only=1
binlog-do-db=shibing_test

replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema

重启从节点:

bash 复制代码
$ sudo docker restart mysql-replica

连接到从节点

bash 复制代码
$ mysql -h 10.211.55.5 -uroot -proot -P 3308
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 9.0.1 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

从节点复制主节点信息配置:

bash 复制代码
MySQL [(none)]> change replication source to source_host='mysql-master', 
source_user='backup', 
source_password='123456', 
source_log_file='mysql-bin.000001', 
source_log_pos=0, 
source_port=3306, 
get_source_public_key=1;


# 重启复制进程, mysql8以前的版本replica换成slave
MySQL [(none)]> stop replica; 
MySQL [(none)]> start replica;
  • 从MySQL9.0以后,change replication source to命令为从节点设置主节点复制信息的命令(MySQL9.0以前是change master to)

From MySQL 8.0.23, use CHANGE REPLICATION SOURCE TO in place of CHANGE

MASTER TO, which is deprecated from that release. In releases before

MySQL 8.0.23

来自参考文档(2)

  • source_host: 主节点名称,这里直接用容器名称即可
  • source_user,source_password:主节点创建的用户名密码,用户从节点复制日志使用,授予replication slave权限
  • source_log_file:开始同步的binlog文件(初始从000001号文件开始)
  • source_log_pos:开始同步的文件位置(初始从0开始)
  • source_port:主机端口,我们是直接连接容器,使用容器开放的端口
  • get_source_public_key: 获取master的公钥。mysql8 以后加密默认使用 caching_sha2_password 插件,需要添加 get_master_public_key=1 选项,8以下版本或者指定加密插件为 mysql_native_password 不需要加
  • In MySQL 9.0, caching_sha2_password is the default authentication

    plugin; mysql_native_password is no longer available.

  • On the server side, two system variables name the RSA private and

    public key-pair files: caching_sha2_password_private_key_path and

    caching_sha2_password_public_key_path. The database administrator must

    set these variables at server startup if the key files to use have

    names that differ from the system variable default values.

  • For replicas, use the CHANGE REPLICATION SOURCE TO statement with the SOURCE_PUBLIC_KEY_PATH option to specify the RSA public key file,

    or the GET_SOURCE_PUBLIC_KEY option to request the public key from the

    source. For Group Replication, the

    group_replication_recovery_public_key_path and

    group_replication_recovery_get_public_key system variables serve the

    same purpose.

    来自参考文档(3)

查看从节点状态:

bash 复制代码
MySQL [performance_schema]> show replica status\G
*************************** 1. row ***************************
             Replica_IO_State: Waiting for source to send event
                  Source_Host: mysql-master
                  Source_User: backup
                  Source_Port: 3306
                Connect_Retry: 60
              Source_Log_File: mysql-bin.000006
          Read_Source_Log_Pos: 768
               Relay_Log_File: fd9ecf27cfbc-relay-bin.000007
                Relay_Log_Pos: 985
        Relay_Source_Log_File: mysql-bin.000006
           Replica_IO_Running: Yes
          Replica_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: mysql,sys,information_schema,performance_schema
           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: 768
              Relay_Log_Space: 1420
              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: 62573dca-88ce-11ef-a9fd-0242ac110005
             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: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Source_TLS_Version: 
       Source_public_key_path: public_key.pem
        Get_Source_public_key: 1
            Network_Namespace: 
1 row in set (0.003 sec)

只要Replica_IO_Running 和 Replica_SQL_Running 都是 yes ,则主从同步就是正常的,只要有一个不是yes则主从同步失败。

错误处理

如果失败可以查看Last_Error、Last_IO_Error、Last_SQL_Error中的错误信息,

该错误信息表示连接主节点错误

Last_IO_Error: Error connecting to source 'backup@mysql-master:3306'.

This was attempt 1/10, with a delay of 60 seconds between attempts.

Message: Access denied for user 'backup'@'172.17.0.6' (using password:

YES)

下面的错误信息表示sql执行错误 Last_SQL_Error: Coordinator stopped because there

were error(s) in the worker(s). The most recent failure being: Worker

1 failed executing transaction 'ANONYMOUS' at source log

mysql-bin.000006, end_log_pos 768. See error log and/or

performance_schema.replication_applier_status_by_worker table for more

details about this failure or others, if any.

详细错误信息可以查看容器日志:

sudo docker logs --tail 50 --follow --timestamps {这里是容器名称}

1.3 验证集群可用性

查看从节点是否已同步主节点的表:

如下从节点已经同步我们在主节点创建的库shibing_test和表example_table

bash 复制代码
MySQL [performance_schema]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| shibing_test       |
| sys                |
+--------------------+
5 rows in set (0.006 sec)

MySQL [performance_schema]> use shibing_test;
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 [shibing_test]> show tables;
+------------------------+
| Tables_in_shibing_test |
+------------------------+
| example_table          |
+------------------------+
1 row in set (0.009 sec)

总结

我这里使用的是MySQL最新镜像,MySQL版本9.0.1,该版本很新,很多操作命令和配置参数都有变化,搭建集群的过程中碰到很多问题。解决问题过程查阅了很多官方文档,下面是列出了我参考的官方文档。

参考

1 https://dev.mysql.com/doc/refman/8.4/en/added-deprecated-removed.html

2 CHANGE REPLICATION SOURCE TO Statement

3 Caching SHA-2 Pluggable Authentication

4 GRANT Statement

相关推荐
甲柒1 小时前
12-Docker发布微服务
java·docker·微服务
abandondyy1 小时前
MySQL---主从复制和读写分离
数据库·mysql
DEARM LINER2 小时前
mysql 巧妙的索引
数据库·spring boot·后端·mysql
Arc星语3 小时前
Docker Redis集群3主3从模式
redis·docker
不惑_3 小时前
Redis与MySQL双写一致性的缓存模式
redis·mysql·缓存
Drscq4 小时前
How to migrate a CentOS 8 to Rocky Linux 8.10
linux·运维·centos
修心光4 小时前
CentOS配置iptables规则并使其永久生效
linux·运维·centos
伏虎山真人5 小时前
开源数据库 - mysql - 组织结构(与oracle的区别)
数据库·mysql·开源
工作不忙6 小时前
不使用docker-compose不使用zookeeper启动ApacheKafka3.8.0单机运行KRAFT模式
ubuntu·docker·zookeeper·kafka·apache
盒马盒马6 小时前
Docker:存储卷
docker·容器