docker实现mysql主从复制

Docker 实现 MySQL 主从复制

搭建一主一从

一台主机用于处理所有 写请求,一台 从机 负责所有 读请求
MySQL 主机对外暴露的端口是 3306 ,从机对外暴露的端口是 3307

创建自定义网络,以便容器之间可以通过主机名和端口互相通信

docker network create mysql

新建主机容器实例,并将其加入到 mysql 自定义网络中

docker run -d -p 3306:3306 --network mysql
–name mysql-master
-v mysql-master:/etc/mysql
-v /var/mysql-master/logs:/var/log/mysql
-v /var/mysql-master/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
-e TZ=Asia/Shanghai
–restart=always mysql:8.0.26
–lower_case_table_names=1
–character-set-server=utf8mb4
–collation-server=utf8mb4_general_ci
–default-authentication-plugin=mysql_native_password

使用的是具名卷,意味着 MySQL 的配置文件在 /var/lib/docker/volumes/目录下的 mysql-master 进行维护

查看主机容器实例

docker ps

列出所有卷

docker volume ls

查看卷详情

docker volume inspect mysql-master

cd /var/lib/docker/volumes/mysql-master/_data

修改主机容器实例的配置文件

vim my.cnf

[mysqld]
#以下是增加的配置
server-id=1 # [必须] 主服务器唯一ID
log-bin=binlog # [必须] 启用二进制日志,指名路径。比如:自己本地的路径/log/mysqlbin
binlog_format=STATEMENT

docker restart mysql-master

新建从机容器实例
并将其加入到 mysql 自定义网络中

docker run -d -p 3307:3306 --network mysql
–name mysql-slave
-v mysql-slave:/etc/mysql
-v /var/mysql-slave/logs:/var/log/mysql
-v /var/mysql-slave/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
-e TZ=Asia/Shanghai
–restart=always mysql:8.0.26
–lower_case_table_names=1
–character-set-server=utf8mb4
–collation-server=utf8mb4_general_ci
–default-authentication-plugin=mysql_native_password

这里我使用的是具名卷,意味着 MySQL 的配置文件在 /var/lib/docker/volumes/目录下的 mysql-slave进行维护

查看从机容器实例

docker ps

列出所有卷

docker volume ls

查看卷详情

docker volume inspect mysql-slave

cd /var/lib/docker/volumes/mysql-slave/_data

修改从机容器实例的配置文件
并重启从机容器实例

vim my.cnf

[mysqld]
#以下是增加的配置
server-id=2 # [必须] 从服务器唯一ID
relay-log=mysql-relay #[可选] 启用中继日志

docker restart mysql-slave

查看自定义网络
查看自定义网络是否有 MySQL 的主机和从机

docker network ls
docker network inspect mysql

主机容器实例:建立账户并授权

docker exec -it mysql-master /bin/bash
mysql -uroot -p123456
CREATE USER ‘slave1’@‘%’ IDENTIFIED BY ‘123456’;
GRANT REPLICATION SLAVE ON . TO ‘slave1’@‘%’;

ALTER USER ‘slave1’@‘%’ IDENTIFIED WITH mysql_native_password BY ‘123456’;

FLUSH PRIVILEGES;

查看 Master 的状态,并记录 File 和 Position 的值

SHOW MASTER STATUS;

执行完此步骤后 不要再操作 MySQL 主机容器实例,防止主服务器的状态值发生变化

从机容器实例:配置需要复制的主机

CHANGE MASTER TO
MASTER_HOST=‘主机的IP地址’,
MASTER_USER=‘主机用户名’,
MASTER_PORT=‘主机的端口号’,
MASTER_PASSWORD=‘主机用户名的密码’,
MASTER_LOG_FILE=‘binlog.具体数字’,
MASTER_LOG_POS=具体值;

docker exec -it mysql-slave /bin/bash
mysql -uroot -p123456

CHANGE MASTER TO
MASTER_HOST=‘mysql-master’,
MASTER_USER=‘slave1’,
MASTER_PASSWORD=‘123456’,
MASTER_LOG_FILE=‘binlog.000006’,
MASTER_LOG_POS=1114;

此处,如果没有写端口,默认是 3306,那么是暴露的 3306 ?当然不是,是内部的端口 3306 ,因为走的是自定义网络,和暴露的外部端口没有任何关系,暴露的外部端口只是让客户端(Java 等)进行远程连接而已,而主从复制之间的通信是不需要外部端口的

启动 Slave 同步

START SLAVE;

查看同步状态

SHOW SLAVE STATUS\G;

注意:如果出现错误,可能的原因如下:
● ① 网络不通。
● ② 账户密码错误。
● ③ 防火墙。
● ④ MySQL 配置文件问题。
● ⑤ 连接服务器时的语法。
● ⑥ 主服务器 MySQL 的权限。

测试:主机容器实例新建库、新建表、插入记录,从机复制

CREATE DATABASE IF NOT EXISTS dbtest CHARACTER SET ‘utf8mb4’ COLLATE ‘utf8mb4_general_ci’;
USE dbtest;
CREATE TABLE student(id INT,name VARCHAR(16));
INSERT INTO student VALUES(1, ‘xxx’);
INSERT INTO student VALUES(2, ‘yyy’);

主机容器实例和从机容器实例查询数据库

USE dbtest;
SELECT * FROM student;

停止主从同步

在从机容器实例停止主从同步
在从机执行

STOP SLAVE;

如果在停止主从同步后,再开启同步命令的时候,报错,可以执行如下的命令

在从机执行

RESET SLAVE;
#删除 SLAVE 数据库的 relay log 日志文件,并重新启用新的 relay log 文件

在主机执行

RESET MASTER;
#删除 Master 中所有的 bing log 文件,并将日志索引文件清空,重新开始所有新的日志文件(慎用)

搭建双主双从

架构
● 一个主机 m1 用于处理所有写请求,它的从机 s1 和另一台主机 m2 还有它的从机 s2 负责所有读请求。当 m1 主机宕机后,m2 主机负责写请求,m1 和 m2 互为备机

首先会创建一个自定义网络 mysql ,然后会启动 4 台 MySQL 容器实例,其中 2 台作为主机,2 台作为从机

编号主机名备注
1m1主机
2s1
3m2主机(备)
4s2从机(备)

创建自定义网络,以便容器之间可以通过主机名和端口互相通信

docker network create mysql

新建 4 台 MySQL 容器实例
2 台容器实例为 MySQL 的主机,2 台容器实例为 MySQL 的从机

docker run -d -p 3306:3306 --network mysql
–name m1
-v m1:/etc/mysql
-v /var/m1/logs:/var/log/mysql
-v /var/m1/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
-e TZ=Asia/Shanghai
–restart=always mysql:8.0.26
–lower_case_table_names=1
–character-set-server=utf8mb4
–collation-server=utf8mb4_general_ci
–default-authentication-plugin=mysql_native_password

docker run -d -p 3307:3306 --network mysql
–name s1
-v s1:/etc/mysql
-v /var/s1/logs:/var/log/mysql
-v /var/s1/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
-e TZ=Asia/Shanghai
–restart=always mysql:8.0.26
–lower_case_table_names=1
–character-set-server=utf8mb4
–collation-server=utf8mb4_general_ci
–default-authentication-plugin=mysql_native_password

docker run -d -p 3308:3306 --network mysql
–name m2
-v m2:/etc/mysql
-v /var/m2/logs:/var/log/mysql
-v /var/m2/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
-e TZ=Asia/Shanghai
–restart=always mysql:8.0.26
–lower_case_table_names=1
–character-set-server=utf8mb4
–collation-server=utf8mb4_general_ci
–default-authentication-plugin=mysql_native_password

docker run -d -p 3309:3306 --network mysql
–name s2
-v s2:/etc/mysql
-v /var/s2/logs:/var/log/mysql
-v /var/s2/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
-e TZ=Asia/Shanghai
–restart=always mysql:8.0.26
–lower_case_table_names=1
–character-set-server=utf8mb4
–collation-server=utf8mb4_general_ci
–default-authentication-plugin=mysql_native_password

查看自定义网络是否有 MySQL 的主机和从机

docker network ls
docker network inspect mysql

列出所有卷

docker volume ls

查看卷详情

docker volume inspect m1
cd /var/lib/docker/volumes/m1/_data

其余,依次类推即可

双主搭建

  • 主机搭建(m1)
    修改主机 m1 容器实例的配置文件,并重启主机容器 m1 实例

vim my.cnf

[mysqld]
#以下是增加的配置
server-id=1
#[必须] 主服务器唯一ID,保证整个集群环境中唯一,取值范围在 1 - 2^32 -1 ,默认为 1
log-slave-updates
#在作为从库的时候,有写入操作也需要更新二进制日志文件

docker restart m1

  • 主机搭建(m2)
    修改主机 m2 容器实例的配置文件,并重启主机容器 m2 实例

vim my.cnf

[mysqld]
#以下是增加的配置
server-id=3
#[必须] 主服务器唯一ID,保证整个集群环境中唯一,取值范围在 1 - 2^32 -1 ,默认为 1
log-slave-updates
#在作为从库的时候,有写入操作也需要更新二进制日志文件

docker restart m2

双从搭建

  • 从机搭建(s1)
    修改从机 s1 容器实例的配置文件,并重启从机容器 s1 实例

vim my.cnf

[mysqld]
#以下是增加的配置
server-id=2
#[必须] 从服务器唯一ID
relay-log=mysql-relay
#[可选] 启用中继日志

docker restart s1

  • 从机搭建(s2)
    修改从机 s2 容器实例的配置文件,并重启从机容器 s2 实例

vim my.cnf

[mysqld]
#以下是增加的配置
server-id=4
#[必须] 从服务器唯一ID
relay-log=mysql-relay
#[可选] 启用中继日志

docker restart s2

双主:建立账户并授权

  • MySQL 主机(m1)创建账号并授权

docker exec -it m1 /bin/bash
mysql -uroot -p123456
CREATE USER ‘slave1’@‘%’ IDENTIFIED BY ‘123456’;
GRANT REPLICATION SLAVE ON . TO ‘slave1’@‘%’;

ALTER USER ‘slave1’@‘%’ IDENTIFIED WITH mysql_native_password BY ‘123456’;

FLUSH PRIVILEGES;

  • MySQL 主机(m2)创建账号并授权

docker exec -it m2 /bin/bash
mysql -uroot -p123456
CREATE USER ‘slave1’@‘%’ IDENTIFIED BY ‘123456’;
GRANT REPLICATION SLAVE ON . TO ‘slave1’@‘%’;

ALTER USER ‘slave1’@‘%’ IDENTIFIED WITH mysql_native_password BY ‘123456’;

FLUSH PRIVILEGES;

  • 查看 MySQL 主机(m1)的状态,并记录 File 和 Position 的值

SHOW MASTER STATUS;

  • 查看 MySQL 主机(m2)的状态,并记录 File 和 Position 的值

SHOW MASTER STATUS;

双从:配置需要复制的主机

从机上复制主机的命令

CHANGE MASTER TO
MASTER_HOST=‘主机的IP地址’,
MASTER_USER=‘主机用户名’,
MASTER_PORT=‘主机的端口号’,
MASTER_PASSWORD=‘主机用户名的密码’,
MASTER_LOG_FILE=‘binlog.具体数字’,
MASTER_LOG_POS=具体值;

示例:s1

docker exec -it s1 /bin/bash
mysql -uroot -p123456

CHANGE MASTER TO
MASTER_HOST=‘m1’,
MASTER_USER=‘slave1’,
MASTER_PASSWORD=‘123456’,
MASTER_LOG_FILE=‘binlog.000003’,
MASTER_LOG_POS=1114;

示例:s2

docker exec -it s2 /bin/bash
mysql -uroot -p123456

CHANGE MASTER TO
MASTER_HOST=‘m2’,
MASTER_USER=‘slave1’,
MASTER_PASSWORD=‘123456’,
MASTER_LOG_FILE=‘binlog.000003’,
MASTER_LOG_POS=1114;

示例:s1 示例:s2
启动 Slave 同步

START SLAVE;

查看同步状态 示例:s1 s2

SHOW SLAVE STATUS\G;

到此为止,我们只是配置了两台主从复制,还没有配置主主复制,请看下面的操作

双主之间的相互复制
查看 Master 的状态,并记录 File 和 Position 的值

示例:m1 m2

SHOW MASTER STATUS;

m2 复制 m1,m1 复制 m2。

CHANGE MASTER TO
MASTER_HOST=‘主机的IP地址’,
MASTER_USER=‘主机用户名’,
MASTER_PORT=‘主机的端口号’,
MASTER_PASSWORD=‘主机用户名的密码’,
MASTER_LOG_FILE=‘binlog.具体数字’,
MASTER_LOG_POS=具体值;

示例:m1

CHANGE MASTER TO
MASTER_HOST=‘m2’,
MASTER_USER=‘slave1’,
MASTER_PASSWORD=‘123456’,
MASTER_LOG_FILE=‘binlog.000003’,
MASTER_LOG_POS=1114;

示例:m2

CHANGE MASTER TO
MASTER_HOST=‘m1’,
MASTER_USER=‘slave1’,
MASTER_PASSWORD=‘123456’,
MASTER_LOG_FILE=‘binlog.000003’,
MASTER_LOG_POS=1114;

启动 Master 同步

示例m1

START SLAVE;

示例m2

START SLAVE;

查看同步状态,示例m1 m2

SHOW SLAVE STATUS\G;

测试,在 m1 和 m2 上执行 DDL 和 DML 语句,查看涉及到的数据库服务器的数据同步情况

示例:m1

#执行 DDL 操作
CREATE DATABASE IF NOT EXISTS dbtest CHARACTER SET ‘utf8mb4’ COLLATE ‘utf8mb4_general_ci’;

USE dbtest;

CREATE TABLE student(id INT,`name` VARCHAR(16));

示例:m2

#执行 DML 操作
USE dbtest;

INSERT INTO student VALUES(1, 'xx');
INSERT INTO student VALUES(2, 'yy');

示例:m1

#查看数据
USE dbtest;
SELECT * FROM student;

示例:m2

#查看数据
USE dbtest;
SELECT * FROM student;

示例:s1

#查看数据
USE dbtest;
SELECT * FROM student;

示例:s2

#查看数据
USE dbtest;
SELECT * FROM student;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值