MySQL容器主从同步

参考文章:

基于Docker实现Mysql主从同步

主从数据库复制+Springboot项目中配置主从数据库读写分离

SpringBoot+Mysql实现读写分离主从复制(二)

mysql实现主从复制/主从同步

SpringBoot 实现 MySQL 读写分离技术

docker实现mysql主从同步

1.0、准备

先准备两个MySQL容器,最好是同版本的

# 主节点对外映射端口3307
sir-2:~ x$ docker run -p 3307:3306 --name master_mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0.22
315e1ecad855b5bbe1589a5f51351b665c8c80efacede7fcff871cea7c16e7dd
# 从节点对外映射端口3308
sir-2:~ x$ docker run -p 3308:3306 --name slave_mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0.22
71c3bb3bcdbf7c67aa19486e112d0a1b19364557b592e55703718f6bb33e3c24
sir-2:~ x$ 

可使用docker ps检查两个容器是否正确运行。

sir-2:~ x$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
71c3bb3bcdbf   mysql:8.0.22   "docker-entrypoint.s…"   1 minutes ago   Up 40 minutes   33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp   slave_mysql
315e1ecad855   mysql:8.0.22   "docker-entrypoint.s…"   2 minutes ago   Up 20 minutes   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   master_mysql
sir-2:~ x

设置主从为相同时区,并尽量使用相同时间服务器,避免时间不一致造成问题。

2.0、配置主节点

  1. 进入容器交互环境,并安装vim以编辑my.cnf。

    # 进入master_mysql的终端交互环境
    sir-2:~ x$ docker exec -it master_mysql /bin/bash
    # 设置时区
    root@315e1ecad855:/# ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    root@315e1ecad855:/# echo 'Asia/Shanghai' >/etc/timezone
    # 更新apt-get
    root@315e1ecad855:/# apt-get update
    Get:1 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB]
    Get:2 http://repo.mysql.com/apt/debian buster InRelease [21.5 kB] 
    ...
    # apt-get安装vim,对所有交互询问都回复yes
    root@315e1ecad855:/# apt-get install vim -y
    Reading package lists... Done
    Building dependency tree       
    ...
    # vim编辑my.cnf
    root@315e1ecad855:/# vim /etc/mysql/my.cnf
  2. my.cnf[mysqld]分区下添加下面内容后保存,exit退出容器交互环境。

    # 同一局域网内唯一ID,如果不配置或置为0,表示主节点拒绝来只从节点的连接。
    server-id=1
    # 二进制日志功能,保存数据库的所有操作,从节点会同步这些二进制日志
    log-bin=mysql-bin
    ​
    # 二进制日志格式,有row、statement、mixed三种格式,
    # row指的是把改变的内容复制过去,而不是把命令在从服务器上执行一遍,
    # statement指的是在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。
    # mixed指的是默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
    # binlog-format=ROW
    ​
    # 设置需要同步的库,有多个就用逗号隔开,也可以不指定,直接同步所有的库
    # binlog-do-db=test
    ​
    # 设置忽略的库
    # binlog-ignore-db=information_schema
  3. 重启容器

    sir-2:~ x$ docker restart master_mysql
    master_mysql
    sir-2:~ x$
  4. 查看server-id是否已经修改

    # 连接mysql
    sir-2:~ x$ mysql -h127.0.0.1 -uroot -p123456 -P3307
    mysql: [Warning] Using a password on the command line interface can be insecure.
    ...
    # 查询
    mysql> show variables like 'server_id';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | server_id     | 1     |
    +---------------+-------+
    1 row in set (0.01 sec)
    ​
    mysql> 
  5. 查看二进制日志文件,记住File和Position字段的内容,配置从节点需要这些数据。

    mysql> show master status;
    +------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000001 |      156 |              |                  |                   |
    +------------------+----------+--------------+------------------+-------------------+
    1 row in set (0.00 sec)
    ​
    mysql> 
  6. 创建数据同步用户,并赋予replication slave和replication client权限。

    # 创建数据同步用户
    mysql> create user 'slave'@'%' identified by '123456';
    Query OK, 0 rows affected (0.01 sec)
    # 为数据同步用户添加权限
    # grant 赋权命令
    # *.*当前用户对所有库和表的相应操作权限
    # 'slave'@'%'权限赋给slave用户,所有IP都能连接
    mysql> grant replication slave, replication client on *.* to 'slave'@'%';
    Query OK, 0 rows affected (0.00 sec)
    ​
    mysql> 
  7. 验证授权是否成功

    mysql> show grants for slave;
    +-------------------------------------------------------------------+
    | Grants for slave@%                                                |
    +-------------------------------------------------------------------+
    | GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO `slave`@`%` |
    +-------------------------------------------------------------------+
    1 row in set (0.01 sec)
    ​
    mysql> 
  8. 退出MySQL,使用新创建的用户slave来测试是否能连接,能正常进入就行。

    sir-2:~ x$ mysql -h127.0.0.1 -P3307 -uslave -p123456
    ...
    mysql> 

3.0、配置从节点

  1. 进入容器交互环境,并安装vim以编辑/etc/mysql/my.cnf。

    sir-2:~ x$ docker exec -it slave_mysql bash
    root@71c3bb3bcdbf:/# ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    root@71c3bb3bcdbf:/# echo 'Asia/Shanghai' >/etc/timezone
    root@71c3bb3bcdbf:/# apt-get update
    ...
    root@71c3bb3bcdbf:/# apt-get install vim -y
    ...
    root@71c3bb3bcdbf:/# vim /etc/mysql/my.cnf
  2. my.cnf[mysqld]分区下添加下面内容后保存,exit退出容器交互环境。

    # 同一局域网内唯一ID
    server-id=2
    # 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
    log-bin=mysql-slave-bin
    # relay_log配置中继日志,从主节点读取的二进制日志文件,写入relay_log中
    relay_log=mysql-relay-bin
    # 配置日志文件
    ​
    # 设置需要复制的库
    # replicate-do-db=zdx
    ​
    # 设置需要复制的表
    # replicate-do-table=tb1
    # 使用通配符设置需要复制的表
    # replicate-wild-do-table=test*
    ​
    log-slave-updates
    # 跳过从库错误
    slave-skip-errors=all
    slave-net-timeout=60
  3. 重启slave容器

    sir-2:~ x$ docker restart slave_mysql
    slave_mysql
    sir-2:~ x$
  4. 查看server-id是否已经修改

    sir-2:~ x$ mysql -h127.0.0.1 -uroot -p123456 -P3308
    ...
    mysql> show variables like 'server_id';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | server_id     | 2     |
    +---------------+-------+
    1 row in set (0.01 sec)
    ​
    mysql>
  5. 查询主节点的容器的独立IP

    sir-2:~ x$ docker inspect --format='{{.NetworkSettings.IPAddress}}'  master_mysql
    172.17.0.2
    sir-2:~ x$ 
  6. 进入从节点MySQL,进行连接到主节点的配置,MASTER_HOST的IP为主节点的独立IP,MASTER_LOG_FILE和MASTER_LOG_POS对应主节点二进制日志文件的对应的值,重启从节点后需要重新执行6-7步骤。

    mysql> CHANGE MASTER TO MASTER_HOST='172.17.0.2', MASTER_PORT=3306,  MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=156, MASTER_CONNECT_RETRY=30, MASTER_BIND='';
    Query OK, 0 rows affected (0.02 sec)
    ​
    mysql> 
  7. 在从节点启动同步用户,启动从数据库的复制线程。

    # 启动slave用户
    mysql> start slave user='slave' password='123456';
    Query OK, 0 rows affected, 1 warning (0.00 sec)
    ​
    # 查看slave状态,查看复制是否成功,返回的Slave_IO_Running和Slave_SQL_Running都是Yes,则成功。
    # Slave_IO_Running:表明与主节点的通信状况,若为no,检查能否ping通主节点,检查主节点防火墙,数据库是否启动等。
    # Slave_SQL_Running:若为no,表明执行sql时出错。
    mysql> show slave status\G;

4.0、测试数据同步

  1. 主节点创建数据库。

    mysql> create database zdx default character set utf8;
    Query OK, 1 row affected, 1 warning (0.01 sec)
    ​
    mysql> create table zdx.tb1 (user varchar(30) not null, age int(10) not null) default charset utf8;
    Query OK, 0 rows affected, 2 warnings (0.02 sec)
    ​
    mysql> insert into zdx.tb1 value ('zhangsan', 18);
    Query OK, 1 row affected (0.00 sec)
    ​
    mysql>

  2. 从数据库是否同步数据,结果显示已经同步数据

    mysql> select * from zdx.tb1;
    +----------+-----+
    | user     | age |
    +----------+-----+
    | zhangsan |  18 |
    +----------+-----+
    1 row in set (0.01 sec)
    ​
    mysql>

5.0、遇到的问题

问题:在从库上show slave status\G时,发现slave_io_running: connecting导致无法同步,日志显示:Last_IO_Error: error connecting to master 'slave@172.17.0.2:3306' - retry-time: 30 retries: 1 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.

解决:MySQL版本8之后启用了新的默认认证插件,解决办法参考下面的前两篇文章。先使用docker exec -it slave_mysql bash进入从库交互环境,需要现在从库上连接主库获取public-key。

sir-2:~ x$ docker exec -it slave_mysql bash
# slave是在主库上面创建的用于复制的账户
root@ccddf8133651:/# mysql --ssl-mode=DISABLED -h172.17.0.2 -uslave -p123456 --get-server-public-key
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 48
Server version: 8.0.22 MySQL Community Server - GPL
​
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
​
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
root@ccddf8133651:/# 

参考文章:

  1. MySQL 8.0 : more about new authentication plugin and replication

  2. slave_io_running: connecting

  3. 注意:MySQL主从不同步问题分析与处理思路

  4. Mysql主从(主从不同步解决办法,常见问题及解决办法)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值