首页 > 数据库 >docker配置mysql一主多从。宿主机Navicat Premium 15通过不同ip连接

docker配置mysql一主多从。宿主机Navicat Premium 15通过不同ip连接

时间:2025-01-07 17:33:20浏览次数:3  
标签:bin Premium relay ip 宿主机 repl mysqld mysql docker

1. 环境准备

1.1 拉取 MySQL 镜像

docker pull mysql:8.0

解释:
从 Docker 官方镜像仓库中拉取 MySQL 8.0 镜像,确保我们使用最新版本。如果已经拉取,可以跳过这步。


1.2 创建自定义网络(二选一)

1.2.1 创建自定义网络(端口不同)
docker network create mysql-cluster

解释:
创建一个名为 mysql-cluster 的 Docker 网络,确保所有容器可以通过网络互相通信。

1.2.2 创建一个具有用户配置子网的网络(ip不同)
docker network ls					##查看所有网络
docker network inspect <网络名字>	##查看指定网络的详细信息
docker network rm mysql-cluster		##删除已经存在的网络
docker stop $(docker ps -a -q)		##停止所有容器运行
docker rm $(docker ps -a -q)		##删除所有停止运行的容器

!!!!!!!!!!!!使用macvlan模式!!!!!!!!!!!

docker network create -d macvlan \
--subnet=192.168.0.0/24 \
--gateway=192.168.0.254 \
-o parent=ens33 \
mysql-cluster

网关与宿主机虚拟机一致gateway=192.168.0.254


2. 启动 MySQL 容器

2.1 启动主节点容器

docker run -d \
--name mysql-master \
--network mysql-cluster \
--ip 192.168.0.100 \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_USER=repl \
-e MYSQL_PASSWORD=replpass \
-v mysql-master-data:/var/lib/mysql \
mysql:8.0
--------------------------------------以下为自定义添加映射和库------------------------------------------
-p 3306:3306 \
-e MYSQL_DATABASE=testdb \

解释:

  • docker run -d: 后台运行容器。
  • --name mysql-master: 容器名称设置为 mysql-master
  • --network mysql-cluster: 将容器加入之前创建的网络 mysql-cluster
  • --ip 192.168.0.100: 指定主节点的固定 IP 地址。如果使用2.2.1循环启动那就不要设置ip没事!!!
  • -e MYSQL_ROOT_PASSWORD=root: 设置 MySQL 的 root 用户密码为 root
  • -e MYSQL_DATABASE=testdb: 创建一个名为 testdb 的测试数据库。
  • -e MYSQL_USER=repl-e MYSQL_PASSWORD=replpass: 创建一个用于复制的用户 repl,密码为 replpass
  • -p 3306:3306: 将容器内部的 3306 端口映射到宿主机的 3306 端口。
  • -v mysql-master-data:/var/lib/mysql: 挂载卷,用于持久化数据库数据。
  • mysql:8.0: 使用 MySQL 8.0 镜像创建容器。

2.2 启动 4 个从节点容器

2.2.1循环直接启动(配置不同端口,本文配置的是不同ip)
for i in {1..4}; do
  docker run -d \
  --name mysql-slave$i \
  --network mysql-cluster \
  -e MYSQL_ROOT_PASSWORD=root \
  -e MYSQL_USER=repl \
  -e MYSQL_PASSWORD=replpass \
  -p 330$i:3306 \
  -v mysql-slave$i-data:/var/lib/mysql \
  mysql:8.0
done

解释:

  • 使用循环创建 4 个从节点,容器名称依次为 mysql-slave1mysql-slave2 等。
  • 每个从节点都加入同一个网络,密码和主节点一致。
  • 使用不同的端口映射,例如 3301、3302 等。
2.2.2一个一个手动启动(配置不同ip)

​ 从节点1:

docker run -d \
--name mysql-slave1 \
--network mysql-cluster \
--ip 192.168.0.101 \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_USER=repl \
-e MYSQL_PASSWORD=replpass \
-v mysql-slave1-data:/var/lib/mysql \
mysql:8.0

​ 从节点2:

docker run -d \
--name mysql-slave2 \
--network mysql-cluster \
--ip 192.168.0.102 \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_USER=repl \
-e MYSQL_PASSWORD=replpass \
-v mysql-slave2-data:/var/lib/mysql \
mysql:8.0

​ 从节点3:

docker run -d \
--name mysql-slave3 \
--network mysql-cluster \
--ip 192.168.0.103 \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_USER=repl \
-e MYSQL_PASSWORD=replpass \
-v mysql-slave3-data:/var/lib/mysql \
mysql:8.0

​ 从节点4:

docker run -d \
--name mysql-slave4 \
--network mysql-cluster \
--ip 192.168.0.104 \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_USER=repl \
-e MYSQL_PASSWORD=replpass \
-v mysql-slave4-data:/var/lib/mysql \
mysql:8.0

3. 配置主节点

3.1 登录主节点

docker exec -it mysql-master mysql -uroot -proot

解释:

  • docker exec -it: 在容器内执行命令,并进入交互模式。
  • mysql -uroot -proot: 登录到 MySQL 数据库,使用 root 用户和密码 root

3.2 创建复制用户和查看日志状态

启动容器创建主库时已经创建了repl,进入主库,检查一下,plugin是否为mysql_native_password。否则会连接成功,参考5解决。如果没有继续操作

SELECT user, host, plugin FROM mysql.user WHERE user = 'repl';

image-20250107165646608

-- 创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'replpass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

解释:

  • CREATE USER: 创建一个用户 repl,允许任意主机访问。
  • GRANT REPLICATION SLAVE: 赋予复制权限。
  • FLUSH PRIVILEGES: 刷新权限设置,确保生效。
SHOW MASTER STATUS;

解释:

  • 查看主节点当前二进制日志文件及其位置,用于从节点同步时对齐。一定要记录file、和position值
    示例输出:
File: mysql-bin.000001
Position: 154

image-20250107165832834

tip:提示用户 ‘repl’@‘%’ 已经存在,因此无法再次创建。

mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'replpass'; ERROR 1396 (HY000): Operation CREATE USER failed for 'repl'@'%' 
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; Query OK, 0 rows affected (0.01 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.02 sec) 

解决方案

​ 1.直接使用现有用户

​ 如果用户已经存在,并且我们刚才执行的 GRANT 权限命令已成功,则可以直接使用当前用户 ‘repl’@‘%’,无需重新创建。继续执行

SHOW MASTER STATUS;

​ 2.删除用户后重建。接着看主库状态。

DROP USER 'repl'@'%';
CREATE USER 'repl'@'%' IDENTIFIED BY 'replpass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

​ 3.查看主节点日志状态

SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| binlog.000006    |  1256    | testdb       |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

记录File、Position!!!!


3.3 编辑主库配置文件

docker exec -it mysql-master bash

**解释:**进入主节点容器的命令行。

cat /etc/my.cnf

**解释:**查看库配置文件命令行。

1.使用 echo 命令删除最后的 [mysqld] 块和其内容:(如果没有忽略此步,进入第2步)

sed -i '/\[mysqld\]/,$d' /etc/my.cnf

​ 使用了上面命令以后再写入

cat <<EOF > /etc/my.cnf
[mysqld]
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
pid-file=/var/run/mysqld/mysqld.pid
server-id=这里是自定义的数字编号
relay-log=mysql-relay-bin

[client]
socket=/var/run/mysqld/mysqld.sock

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

2.将新配置直接添加到第一个 [mysqld] 段:

只需输入第一条命令(默认不需要执行)

echo -e "[mysqld]\nserver-id=1\nlog-bin=mysql-bin" >> /etc/my.cnf
echo -e "[mysqld]\nserver-id=1\nlog-bin=mysql-bin" | sudo tee -a /etc/my.cnf
echo -e "\n[mysqld]\nserver-id=1\nlog-bin=mysql-bin\nbinlog-do-db=testdb" | sudo tee -a /etc/my.cnf

主1 需要启用二进制日志(log-bin)
log-bin=mysql-bin			启用二进制日志
\n 							换行符
tee -a						不会覆盖已有内容
binlog-do-db=testdb			同步testdb数据库
replicate-ignore-db=testdb	不同步testdb数据库
replicate-ignore-table=表	表级过滤

3.4 编辑从库配置文件

只需输入第一条命令(配置从库,必须要执行的,每段的第一条)

echo -e "\n[mysqld]\nserver-id=11\nrelay-log=mysql-relay-bin" >> /etc/my.cnf
echo -e "[mysqld]\nserver-id=11\nrelay-log=mysql-relay-bin\nread-only=1" | sudo tee /etc/my.cnf
从1	从库必须启用中继日志(relay-log)
relay-log=mysql-relay-bin	启用中继日志
replicate-do-db=testdb		从库只同步主库testdb库
replicate-ignore-db=testdb	排除testdb库不同步
从节点只读权限:read-only=1,tee覆盖配置,避免重复冲突

echo -e "\n[mysqld]\nserver-id=12\nrelay-log=mysql-relay-bin" >> /etc/my.cnf
echo -e "[mysqld]\nserver-id=12\nrelay-log=mysql-relay-bin\nread-only=1" | sudo tee /etc/my.cnf
从2

echo -e "\n[mysqld]\nserver-id=13\nrelay-log=mysql-relay-bin" >> /etc/my.cnf
echo -e "[mysqld]\nserver-id=13\nrelay-log=mysql-relay-bin\nread-only=1" | sudo tee /etc/my.cnf
从3

echo -e "\n[mysqld]\nserver-id=14\nrelay-log=mysql-relay-bin" >> /etc/my.cnf
echo -e "[mysqld]\nserver-id=14\nrelay-log=mysql-relay-bin\nread-only=1" | sudo tee /etc/my.cnf
从4

验证配置文件内容:

cat /etc/my.cnf

确保最终的 [mysqld] 块类似以下内容:

主[mysqld]
server-id=1
log-bin=mysql-bin
binlog-do-db=testdb
##忽略主

从[mysqld] 
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 
pid-file=/var/run/mysqld/mysqld.pid 
server-id=2 
relay-log=mysql-relay-bin

重启所有容器(主可不要):

docker restart $(docker ps -a -q)

4. 配置从节点

4.1 登录依次进入从库修改

docker exec -it mysql-slave1 bash					进入bash编辑配置文件

4.2 依次修改每隔从库配置文件

echo -e "\n[mysqld]\nserver-id=11\nrelay-log=mysql-relay-bin" >> /etc/my.cnf
echo -e "[mysqld]\nserver-id=11\nrelay-log=mysql-relay-bin\nread-only=1" | sudo tee /etc/my.cnf
从1	从库必须启用中继日志(relay-log)
relay-log=mysql-relay-bin	启用中继日志
replicate-do-db=testdb		从库只同步主库testdb库
replicate-ignore-db=testdb	排除testdb库不同步
从节点只读权限:read-only=1,tee覆盖配置,避免重复冲突

echo -e "\n[mysqld]\nserver-id=12\nrelay-log=mysql-relay-bin" >> /etc/my.cnf
echo -e "[mysqld]\nserver-id=12\nrelay-log=mysql-relay-bin\nread-only=1" | sudo tee /etc/my.cnf
从2

echo -e "\n[mysqld]\nserver-id=13\nrelay-log=mysql-relay-bin" >> /etc/my.cnf
echo -e "[mysqld]\nserver-id=13\nrelay-log=mysql-relay-bin\nread-only=1" | sudo tee /etc/my.cnf
从3

echo -e "\n[mysqld]\nserver-id=14\nrelay-log=mysql-relay-bin" >> /etc/my.cnf
echo -e "[mysqld]\nserver-id=14\nrelay-log=mysql-relay-bin\nread-only=1" | sudo tee /etc/my.cnf
从4

4.3 重启容器

exit  ##退出并重启
docker restart mysql-slave1

4.4 登录数据库

docker exec -it mysql-slave1 mysql -uroot -proot

4.5 配置主从同步

STOP SLAVE;
RESET SLAVE;

CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='repl',
MASTER_PASSWORD='replpass',
MASTER_LOG_FILE='binlog.000008',
MASTER_LOG_POS=157;

START SLAVE;

解释:

  • MASTER_HOST: 指定主节点的地址。
  • MASTER_USERMASTER_PASSWORD: 使用主节点上配置的复制用户和密码。
  • MASTER_LOG_FILEMASTER_LOG_POS: 使用主节点日志文件和位置,确保数据一致性。
  • START SLAVE: 启动复制进程。

4.6 查看状态

SHOW SLAVE STATUS \G;

4.7 成功标志

  1. 确认 Slave_IO_RunningSlave_SQL_Running 都是 Yes
  2. 确认 Seconds_Behind_Master0 或较小值。

5 配置错误提示

Last_IO_Error: Error connecting to source 'repl@mysql-master:3306'. This was attempt 1/86400, with a delay of 60 seconds between attempts. Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
1. 在主节点中修改用户认证插件

登录主节点:

docker exec -it mysql-master mysql -uroot -proot

修改用户认证插件为 mysql_native_password

ALTER USER 'repl'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'replpass';
FLUSH PRIVILEGES;

检查用户的认证插件:

SELECT user, host, plugin FROM mysql.user WHERE user = 'repl';

确保输出中 pluginmysql_native_password

image-20250107155951686

image-20250107160025944


2. 在从节点重置连接并重新配置主从

登录从节点:

docker exec -it mysql-slave1 mysql -uroot -proot

停止复制并重置状态:

STOP SLAVE;
RESET SLAVE;

重新配置主从:

CHANGE MASTER TO
MASTER_HOST='192.168.0.182',
MASTER_USER='repl',
MASTER_PASSWORD='replpass',
MASTER_LOG_FILE='binlog.000006',
MASTER_LOG_POS=157;

START SLAVE;

查看状态:

SHOW SLAVE STATUS \G;
  1. 确认 Slave_IO_RunningSlave_SQL_Running 都是 Yes
  2. 确认 Seconds_Behind_Master0 或较小值。

成功!

标签:bin,Premium,relay,ip,宿主机,repl,mysqld,mysql,docker
From: https://blog.csdn.net/qq_41710568/article/details/144989867

相关文章

  • Java Spring Boot实现基于URL + IP访问频率限制
    点击下载《JavaSpringBoot实现基于URL+IP访问频率限制(源代码)》1.引言在现代Web应用中,接口被恶意刷新或暴力请求是一种常见的攻击手段。为了保护系统资源,防止服务器过载或服务不可用,需要对接口的访问频率进行限制。本文将介绍如何使用SpringBoot实现基于URL......
  • Is iPad good or bad for middle school students?iPad 对中学生是好还是坏?
    IsiPadgoodorbadformiddleschoolstudents?iPad对中学生是好还是坏?1写作要求假如你是李华,是一名初中生。随着科技的发展,iPad已成为中学生的新宠。用iPad既可以听音乐,阅读纯文本电子书,又可以玩电子游戏。请你用英语给某英语报社写一篇短文,谈谈中学生使用iPad的利弊。内......
  • vim启动速度优化小结(基于vim9script)
    源码编译./configure--prefix=$HOME/.usr/local/--without-x--enable-gui=no测试版本VIM-ViIMproved9.1(2024Jan02,compiledJan7202514:30:02)Includedpatches:1-993测试脚本#!/usr/bin/envbashcnt=0>startup.txtwhiletruedovim--no......
  • 配置NQA for IPv4静态路由示例
    通过配置NQAforIPv4静态路由可以快速检测到网络的故障,控制静态路由的发布,实现业务切换。组网需求当网络比较简单,或者路由器不能通过动态路由协议建立到达目的网络的路由时,可以配置静态路由。但是,与动态路由协议不同,静态路由自身没有检测机制,当网络发生故障时,静态路由无法......
  • ROS-noetic+UR5上安装robotiq_85_gripper夹爪
    夹抓(未配置控制器,无中间过程)ROS-noetic+UR5上安装robotiq_85_gripper夹爪 夹抓(可运行,详细配置过程,依赖最新代码)在UR5机械臂末端添加robotiq2f85夹爪并在Gazebo中仿真 相机+夹抓+待抓取物体(可直接运行,无中间过程)ros1noetic跑UR5_gripper_camera_gazebo 相机+......
  • 30 个鲜为人知的 JavaScript 技巧,让你的代码更具可读性
    1、使用!!转换为布尔值使用双重否定快速将任何值转换为布尔值。lettruthyValue=!!1;//trueletfalsyValue=!!0;//false2、默认函数参数设置函数参数的默认值以避免定义错误。functiongreet(name="Guest"){return`Hello,${name}!`;}3、......
  • Javascript实现asp.net mvc的checkbox基本功能
    Html的checkbox使用很广的,它的状态,勾选与非选。 初始状态,默认为非选。你可以设置它是勾选,直在checkbox标签中,添加checked属性。另外,在javascript可以这样,getById('Checkbox_IsPublished').checked=true; 或者,getById('Checkbox_IsPublished').setAttribute('chec......
  • 题解:P1541 [NOIP2010 提高组] 乌龟棋
    基础动态规划。这道题的题目条件显然满足阶段性和无后效性,那么有一个直观的思路就是把当前所处格子和四种卡片的使用次数作为状态。但是如果按照上面的想法,数组空间是无法开下的,所以我们稍微变一下思路,把四种卡片的使用数量作为状态,对于当前所处格子的话可以直接计算出来,这样数......
  • CICD Day5、Jenkins pipline
    在创建web-demo项目的时候,使用的是freestyleproject自由风格项目类型。此外,jenkins还提供了pipline项目类型(又称流水线),它具有以下特点:基于代码的描述:通过代码描述整个构建过程,pipline脚本可以被存储在代码仓库中进行版本管理。团队成员还可以通过查看脚本来了解整个软件交付......
  • 安装 Eclipse
    我从礼拜一开始就一直研究这个问题,这个问题在我脑袋中一点概念都没有。我们在解决自己不知道的问题的时候,首先,先把问题定义清楚。 举个例子,我昨天把问题定义成,1.Eclipse部署Tomcat;2.Linuxtomcattomcat 搜出的结果,都是在图形界面上操作,这时候我有两种选择:一是Eclipse......