MySQL8.0.43在anolis8.10容器化双主部署

系统:anolis8.10

镜像版本:MySQL8.0.43

第一步:停止并删除现有 MySQL 容器

分别在 LongXi110​ 和 LongXi111​ 上执行:docker ps | grep mysql

如果发现有其他运行中的容器:

停止容器(假设容器名为 mysql-node1 / mysql-node2)
docker stop mysql-node1  
docker stop mysql-node2   

 删除容器(连同其存储层一起删除)
docker rm mysql-node1    
docker rm mysql-node2    

第二步:准备新的 MySQL 配置文件(my.cnf)

我们需要在两台机器上分别准备好双主配置的 my.cnf 文件,以便在创建容器时挂载进去。

node1

[mysqld]

server-id=1
log-bin=mysql-bin
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
log-slave-updates = ON
auto-increment-offset = 1
auto-increment-increment = 2
sync-binlog = 1
innodb_flush_log_at_trx_commit = 1

host-cache-size=0
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
[client]
socket=/var/run/mysqld/mysqld.sock

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

node2

[mysqld]

server-id = 2

log-bin = mysql-bin
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
log-slave-updates = ON
auto-increment-offset = 2
auto-increment-increment = 2
sync-binlog = 1
innodb_flush_log_at_trx_commit = 1

host-cache-size=0
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
[client]
socket=/var/run/mysqld/mysqld.sock

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

第三步:创建并启动新的 MySQL 容器

node1:

docker run -d \
  --name mysql-node1 \
  --restart always \
  -p 3306:3306 \
  -v /opt/mysql/mysql_data:/var/lib/mysql \ #引号左边填你要挂载的数据目录
  -v /root/docker-mysql/mysql/conf:/etc/mysql/conf.d \  #引号左边填你要挂载的my.cnf的位置
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:8.0.43

node2:

docker run -d \
  --name mysql-node2 \
  --restart always \
  -p 3306:3306 \
  -v /opt/mysql/mysql_data:/var/lib/mysql \ #引号左边填你要挂载的数据目录
  -v /root/docker-mysql/mysql/conf:/etc/mysql/conf.d \  #引号左边填你要挂载的my.cnf的位置
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:8.0.43

第四步:验证容器启动和配置生效

分别进入两个容器,检查配置是否正确加载。

# 在 LongXi110 上
docker exec -it mysql-node1 mysql -uroot -p
# 输入密码后执行:
SHOW VARIABLES LIKE 'server_id';
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'auto_increment_offset';
SHOW VARIABLES LIKE 'auto_increment_increment';

预期结果:

  • server_id = 1

  • log_bin = ON

  • auto_increment_offset = 1

  • auto_increment_increment = 2

同样的方法检查 node2,预期 server_id = 2,offset = 2,increment = 2。

第五步:登录各自 MySQL 容器

# 在 LongXi110 上
docker exec -it mysql-node1 mysql -uroot -p

# 在 LongXi111 上
docker exec -it mysql-node2 mysql -uroot -p

在 node1 (110) 上:

CREATE USER 'repl_user'@'192.168.199.%' IDENTIFIED WITH mysql_native_password BY '你的强密码';
 #'%'的意思是任意,各位参照自己的ip修改前三位
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.199.%';
FLUSH PRIVILEGES;

在 node2 (111) 上:

CREATE USER 'repl_user'@'192.168.199.%' IDENTIFIED WITH mysql_native_password BY '你的强密码';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.199.%';
FLUSH PRIVILEGES;

配置 CHANGE MASTER TO

在 node1 (110) 上查看:

SHOW MASTER STATUS;

记下 FilePosition 的值,例如 mysql-bin.000001157

在 node2 (111) 上查看:

SHOW MASTER STATUS;

同样记下 FilePosition 的值。

配置相互的主从关系:

在 node1 (110) 上,配置指向 node2 (111):

CHANGE MASTER TO
    MASTER_HOST = '192.168.199.111',
    MASTER_USER = 'repl_user',
    MASTER_PASSWORD = '你的强密码',
    MASTER_LOG_FILE = 'mysql-bin.000001',  -- 替换为你在 node2 上 SHOW MASTER STATUS 得到的 File
    MASTER_LOG_POS = 157;                 -- 替换为对应的 Position

在 node2 (111) 上,配置指向 node1 (110):

CHANGE MASTER TO
    MASTER_HOST = '192.168.199.110',
    MASTER_USER = 'repl_user',
    MASTER_PASSWORD = '你的强密码',
    MASTER_LOG_FILE = 'mysql-bin.000001',  -- 替换为你从node1获取的File值
    MASTER_LOG_POS = 157;                  -- 替换为你从node1获取的Position值

启动从库复制

在两个节点上分别执行:

START SLAVE;

验证复制状态

这是最关键的一步,确保一切正常。

在两个节点上分别执行:

SHOW SLAVE STATUS\G

检查输出中的两个关键指标,它们都必须显示为 Yes

  • Slave_IO_Running: Yes

  • Slave_SQL_Running: Yes

如果出现 NoConnecting,请根据 Last_IO_ErrorLast_SQL_Error 的提示排查问题(常见原因:网络不通、密码错误、防火墙、MASTER_LOG_FILE/POS 不正确)。

验证双主功能

现在,你可以进行简单的测试:

  1. node1 上创建一个数据库或表,插入一条数据。

  2. 立即登录 node2,查看该数据库和表是否存在,数据是否同步。

  3. 反过来,在 node2 上插入另一条数据。

  4. 回到 node1 查看,新数据也应该同步过来了。

如果以上测试都通过,恭喜你,双主复制配置成功!auto-increment-offsetauto-increment-increment 的设置确保了即使两边同时插入数据,也不会产生主键冲突。

附:如果node1和node2的数据不同步,得先强行同步!

在 node1 上导出数据(包含所有库):

docker exec mysql-node1 mysqldump -uroot -p --all-databases --source-data=2 > /tmp/full_dump.sql

将 dump 文件传到 node2 所在机器(或用共享卷):

scp /tmp/full_dump.sql root@192.168.199.111:/tmp/

在 node2 上导入数据:

docker exec -i mysql-node2 mysql -uroot -p < /tmp/full_dump.sql

导入后,重新配置复制(因为 dump 包含了 CHANGE MASTER TO 语句,但为了保险,手动重配):

node1,​node2分别执行:

STOP SLAVE;
RESET SLAVE ALL;

CHANGE MASTER TO
    MASTER_HOST='192.168.199.110',
    MASTER_USER='repl_user',
    MASTER_PASSWORD='你的密码',
    MASTER_LOG_FILE='mysql-bin.xxxxxx',  -- SHOW MASTER STATUS;获取
    MASTER_LOG_POS=xxxx;                 -- SHOW MASTER STATUS;获取
START SLAVE;

这种方法的缺点是停机时间长,且需要处理双向同步的顺序。​ 对于实验环境,更推荐先排查配置问题。

关机前操作(在两台机器上都做)

1. 进 MySQL,停掉复制线程(可选但稳妥)

STOP SLAVE;

不停也行,MySQL 重启后会自动从 relay-log 和恢复点继续跑,但主动停一下更干净,避免关机过程中 relay-log 写到一半。

2. 记一下当前 binlog 位置(方便下次出问题回查)

SHOW MASTER STATUS\G
SHOW SLAVE STATUS\G

Master_Log_File / Read_Master_Log_Pos / Exec_Master_Log_Pos 抄下来或截图,下次开机对得上就说明没丢。

3. 退出容器,停 MySQL 服务(比直接关宿主机温柔)

# 容器内
mysqladmin -uroot -p shutdown
# 或者宿主机直接
docker stop mysql-node1

两台都停完,再关宿主机。


下次开机后的恢复流程

1. 启动容器

docker start mysql-node1   # 110
docker start mysql-node2   # 111

如果当初 run 时加了 --restart always,开机自动就起了,这步可以省。

2. 进 MySQL 验状态

SHOW SLAVE STATUS\G

看两个指标:

  • Slave_IO_Running: Yes

  • Slave_SQL_Running: Yes

如果都是 Yes,Seconds_Behind_Master 很快掉到 0,说明双主自动续上了,不用动。

3. 如果 IO/SQL 不是 Yes(极少情况)

START SLAVE;

一般就能拉起来,因为 master.info 和 relay-log 都在,位置没丢。

4. 验数据同步

node1 插一行,node2 查一下,通了就继续实验。


几个下次开机容易踩的小坑

  • 宿主机 IP 变了:如果 192.168.199.110/111 是 DHCP 分配的,关机再开可能 IP 漂了,双主就会连不上。建议龙蜥里把这两台 IP 设成静态,或者在路由器/DHCP 里绑 MAC。

  • 防火墙:龙蜥默认 firewalld 如果开了,3306 得放行,不然 IO 线程 Connecting

  • 容器时区/时间:如果宿主机时间跳变大,binlog 时序没事,但你自己看 SHOW SLAVE STATUS 的时间戳会乱,不影响复制。

posted @ 2026-07-24 20:09  GuiGui321  阅读(10)  评论(0)    收藏  举报