mysql5.7-基于docker-compose搭建主从同步

一、环境信息

  • 系统版本:CentOS Linux release 7.9.2009 (Core)
    • cat /etc/centos-release
  • Docker版本:Docker version 20.10.6, build 370c289
    • docker --version
  • Docker-compose版本:Docker Compose version v2.10.2
    • docker-compose --version
  • MySQL版本:5.7
    • mysql> select version()
  • 主机两台 或者 单台部署两个容器

二、主从复制说明

1、简单了解下binlog

  • binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。
  • binlog日志包括两类文件:二进制日志索引文件(文件名后缀为.index)用于记录所有的二进制文件,二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML(除了数据查询语句)语句事件。
  • binlog有三种格式:statement基于sql语句复制、row基于行数据变更的复制、mixed混合前两种格式的复制。

2、主从复制原理

  1. Master将改变记录到二进制日志(binary log)中
  2. Slave将Master的二进制日志事件(binary log events)拷贝到它的中继日志(relay log)
  3. Slave重做中继日志(Relay Log)中的事件,将Master上的改变反映到它自己的数据库中
  4. 这些是由从库在做,所以是异步的数据同步

3、主从复制应用场景

  1. 主从服务器互为备份,加强数据库架构的健壮性
  2. 主从服务器读写分离,分担网站压力,从服务器只处理用户的查询请求
  3. 将从服务器,按照业务拆分,分担压力

三、master主节点配置

1、目录结构

.
├── docker-compose.yml
└── mysql
    └── conf
    │   └── my.cnf
    └── data
    └── log

需要 docker-compose.ymlmy.cnf 两个文件

2、my.cnf配置文件

创建文件夹

mkdir -p mysql/conf

配置文件

cat >> mysql/conf/my.cnf <<EOF

# @Author: Johnny
# master

[mysqld]

# [必须]服务器唯一ID
server-id=104

# [必须]启用二进制日志
log-bin=mysql-bin 

# 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql

# 确保binlog日志写入后与硬盘同步
sync_binlog = 1

# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all     

# default
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

#log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

EOF

3、docker-compose.yml


# @Author: Johnny

version: '3'
services:
  mysql:
    container_name: mysql-master
    image: mysql:5.7
    restart: always
    volumes:
      - $PWD/mysql/log:/var/log/mysql  
      - $PWD/mysql/conf/my.cnf:/etc/mysql/my.cnf
      - $PWD/mysql/data:/var/lib/mysql
    ports:
      - '3306:3306'
    command: [
        '--explicit_defaults_for_timestamp=true',
        '--character-set-server=utf8mb4',
        '--collation-server=utf8mb4_general_ci',
        '--max_connections=3000'
    ]
    environment:
      MYSQL_ROOT_PASSWORD: "shield"

将上面的内容准备好后,安装:

docker-compose up -d

4、配置主从同步账号和权限

进入容器

docker exec -it mysql-master bash

登录mysql

mysql -uroot -pshield

执行sql

# 查看配置的服务ID,显示的应该是配置的ID
mysql> show variables like '%server_id%';
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| server_id      | 104   |
| server_id_bits | 32    |
+----------------+-------+

# 看master信息 File 和 Position 从服务上要用
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 |              | mysql            |                   |
+------------------+----------+--------------+------------------+-------------------+

# 创建同步账户并开启权限,只是同步账号
mysql> create user 'sync'@'%' identified by '123456';
mysql> grant replication slave,replication client on *.* to 'sync'@'%';

# 刷新信息生效
mysql> flush privileges;

四、slave从节点配置(备份节点)

如果是一台主机安装2个mysql,注意更新 docker-compose.yml 中的端口,避免端口冲突

1、目录结构

.
├── docker-compose.yml
└── mysql
    └── conf
    │   └── my.cnf
    └── data
    └── log

需要 docker-compose.ymlmy.cnf 两个文件

2、my.cnf配置文件

创建文件夹

mkdir -p mysql/conf

配置文件

cat >> mysql/conf/my.cnf <<EOF

cat >> mysql/conf/my.cnf <<EOF

# @Author: Johnny
# slave

[mysqld]
# [必须]服务器唯一ID
server-id=106

# [必须]启用二进制日志
log-bin=mysql-bin 

# 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql

# 确保binlog日志写入后与硬盘同步
sync_binlog = 1

# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all     

# relay_log配置中继日志
relay_log=mysql-relay-bin  

# log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1  

# default 
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

#log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

EOF

3、docker-compose.yml


# @Author: Johnny

version: '3'
services:
  mysql:
    container_name: mysql-slave
    image: mysql:5.7
    restart: always
    volumes:
      - $PWD/mysql/log:/var/log/mysql  
      - $PWD/mysql/conf/my.cnf:/etc/mysql/my.cnf
      - $PWD/mysql/data:/var/lib/mysql
    ports:
      - '3306:3306'
    command: [
        '--explicit_defaults_for_timestamp=true',
        '--character-set-server=utf8mb4',
        '--collation-server=utf8mb4_general_ci',
        '--max_connections=3000'
    ]
    environment:
      MYSQL_ROOT_PASSWORD: "shield"

将上面的内容准备好后,安装:

docker-compose up -d

4、链接master节点

docker exec -it mysql-slave bash
mysql -uroot -pshield

执行sql

#查看server_id是否生效
mysql> show variables like '%server_id%';
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| server_id      | 106   |
| server_id_bits | 32    |
+----------------+-------+

# 连接主mysql服务 master_log_file 和 master_log_pos的值要填写主master里查出来的值 注意这里使用的docker-compose 内部服务的端口和ip,实际应该为真实的master_host,参数看后面的介绍
mysql> change master to master_host='mysql-master',master_user='sync',master_password='123456',master_port=3306,master_log_file='mysql-bin.000001', master_log_pos=154,master_connect_retry=30;

######################################################
###  连接主mysql参数说明:
###  master_port:Master的端口号,指的是容器的端口号
###  master_user:用于数据同步的用户
###  master_password:用于同步的用户的密码
###  master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
###  master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
###  master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
######################################################


# 开启slave
mysql> start slave;

mysql> show slave status \G   
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: mysql-master
                  Master_User: sync
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 1166
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 1334
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_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_Master_Log_Pos: 1166
              Relay_Log_Space: 1543
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 888
                  Master_UUID: 05f48dfa-4afd-11ee-821c-0242ac170002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.01 sec)

看到下列信息代表链接成功

Slave_IO_Running:Yes;
Slave_SQL_Running:Yes;

五、常见问题

1、常用命令

stop slave;
start slave;
show slave status;

2、设置从服务器slave为只读模式(可选)

SHOW VARIABLES LIKE '%read_only%'; #查看只读状态

SET GLOBAL super_read_only=1; #super权限的用户只读状态 1.只读 0:可写
SET GLOBAL read_only=1; #普通权限用户读状态 1.只读 0:可写
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 首先,在两个不同的主机上分别安装dockerdocker-compose。 2. 在其中一个主机上创建一个名为`docker-compose.yml`的文件,如下所示: ``` version: '3' services: master: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: testdb volumes: - ./master-init:/docker-entrypoint-initdb.d ports: - "3306:3306" networks: - db-network command: --server-id=1 --log-bin=mysql-bin --binlog-do-db=testdb slave: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: password volumes: - ./slave-init:/docker-entrypoint-initdb.d ports: - "3307:3306" networks: - db-network command: --server-id=2 --log-bin=mysql-bin --binlog-do-db=testdb --relay-log=mysqld-relay-bin --relay-log-index=mysqld-relay-bin.index --read-only=1 --replicate-do-db=testdb networks: db-network: ``` 在该文件中,我们定义了两个服务:`master`和`slave`。`master`服务使用mysql:5.7镜像,并将其端口映射到主机的3306端口。 `slave`服务也使用mysql:5.7镜像,并将其端口映射到主机的3307端口。我们还定义了一个`db-network`网络,以使两个服务能够相互通信。 3. 在同一台主机上创建一个名为`master-init`的文件夹,并在其中创建一个名为`init.sql`的文件,如下所示: ``` CREATE DATABASE testdb; CREATE TABLE testdb.users ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL ); INSERT INTO testdb.users (username, email) VALUES ('john', 'john@example.com'), ('jane', 'jane@example.com'); ``` 在这个文件中,我们定义了一个名为`testdb`的数据库,以及一个名为`users`的表,然后插入了一些数据。 4. 在同一台主机上创建一个名为`slave-init`的文件夹,并在其中创建一个名为`init.sql`的文件,如下所示: ``` CHANGE MASTER TO MASTER_HOST='master', MASTER_USER='root', MASTER_PASSWORD='password', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; START SLAVE; ``` 在这个文件中,我们定义了`slave`服务的主服务器是`master`,用户名为`root`,密码为`password`,并指定了主服务器的端口和binlog文件的名称和位置。然后,我们启动了从服务器。 5. 在同一台主机上打开终端,切换到包含`docker-compose.yml`文件的目录,并运行以下命令: ``` docker-compose up ``` 这将启动两个服务:`master`和`slave`。在输出中,您应该看到MySQL服务器已成功启动,并且主从复制已经开始。 6. 测试主从复制是否正常工作。我们可以使用以下命令登录到`master`服务器的MySQL shell: ``` mysql -h localhost -u root -p ``` 然后,我们可以使用以下命令创建一个新用户: ``` USE testdb; INSERT INTO users (username, email) VALUES ('mike', 'mike@example.com'); ``` 现在,我们可以使用以下命令登录到`slave`服务器的MySQL shell: ``` mysql -h localhost -P 3307 -u root -p ``` 然后,我们可以使用以下命令检查是否已成功复制数据: ``` USE testdb; SELECT * FROM users; ``` 如果一切正常,您将看到`users`表中包含了新创建的`mike`用户。 这就是使用docker-compose搭建MySQL主从复制的整个过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值