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-slave1
、mysql-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';
-- 创建复制用户
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
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_USER
和MASTER_PASSWORD
: 使用主节点上配置的复制用户和密码。MASTER_LOG_FILE
和MASTER_LOG_POS
: 使用主节点日志文件和位置,确保数据一致性。START SLAVE
: 启动复制进程。
4.6 查看状态
SHOW SLAVE STATUS \G;
4.7 成功标志
- 确认
Slave_IO_Running
和Slave_SQL_Running
都是 Yes。 - 确认
Seconds_Behind_Master
是 0 或较小值。
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';
确保输出中 plugin 是 mysql_native_password
。
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;
- 确认
Slave_IO_Running
和Slave_SQL_Running
都是 Yes。 - 确认
Seconds_Behind_Master
是 0 或较小值。
成功!
标签:bin,Premium,relay,ip,宿主机,repl,mysqld,mysql,docker From: https://blog.csdn.net/qq_41710568/article/details/144989867