基于 GTID 的 MySQL 主从(M-S)复制完整部署步骤(Docker 环境)

以下步骤严格区分主服务器(Master,IP:192.168.1.190)和从服务器(Slave,IP:192.168.1.196)操作,包含环境准备、配置修复、网络排查、同步验证全流程,确保每一步可落地。

一、前置环境准备(主、从服务器均执行)

  1. 安装 Docker 与 MySQL 镜像

bash

# 1. 安装Docker(若未安装)
yum install docker -y
systemctl start docker
systemctl enable docker

# 2. 拉取MySQL 5.7镜像(支持GTID,稳定兼容,如需其他版本需修改标签)
docker pull mysql:5.7  # ← 如需其他版本(如5.7.40),可替换为mysql:5.7.40

# 3. 安装基础工具(后续网络测试、权限操作需用到)
yum install net-tools nc -y
  1. 清理历史残留(若之前部署过 MySQL 容器)

bash

# 停止并删除所有MySQL容器(避免端口/配置冲突)
docker stop $(docker ps -aq --filter "name=mysql-*") 2>/dev/null
docker rm $(docker ps -aq --filter "name=mysql-*") 2>/dev/null

# 删除旧挂载目录(首次部署可跳过,避免配置残留,路径需与后续一致)
rm -rf /docker/mysql 2>/dev/null  # ← 若自定义挂载目录,需同步修改此处路径

二、主服务器(192.168.1.190)操作:配置 GTID 与复制用户

  1. 创建挂载目录与 GTID 配置文件

bash

# 1. 创建主库数据、配置目录(路径可自定义,需与后续挂载一致)
mkdir -p /docker/mysql/master/data /docker/mysql/master/conf  # ← 若修改路径,后续挂载需同步变更

# 2. 编写GTID核心配置文件(my.cnf)
cat > /docker/mysql/master/conf/my.cnf << EOF
[mysqld]
# 基础标识(主从必须唯一,主库设为10,从库需不同)
server-id = 10  # ← 可自定义(如1、100等),但需与从库server-id不同
# 二进制日志(GTID依赖,记录事务,路径可自定义)
log_bin = /var/lib/mysql/mysql-bin  # ← 容器内路径,若修改需确保目录可写
log_bin_index = /var/lib/mysql/mysql-bin.index
# GTID关键配置
gtid_mode = ON                  # 启用GTID模式(固定值,无需修改)
enforce_gtid_consistency = ON   # 强制GTID事务一致性(固定值,无需修改)
log_slave_updates = 1           # 允许从库同步的事务写入自身binlog(固定值,无需修改)
# 其他配置
binlog_format = ROW             # 推荐ROW模式,避免SQL兼容问题(固定值,无需修改)
expire_logs_days = 7            # binlog保留7天,可根据磁盘空间修改(如30天)
character-set-server = utf8mb4  # 统一字符集(可根据需求修改,如utf8)
collation-server = utf8mb4_unicode_ci
default_storage_engine = InnoDB # 仅支持InnoDB(GTID不支持MyISAM,固定值)
EOF

# 3. 修正配置文件权限(避免MySQL因安全问题忽略配置)
chmod 644 /docker/mysql/master/conf/my.cnf
  1. 启动主库容器

bash

docker run -d \
  --name mysql-master \  # 容器名可自定义(如master-db)
  -p 3306:3306 \  # 主机端口:容器端口,若3306被占用,改为主机端口如3307:3306 ← 需修改主机端口(左侧)
  -v /docker/mysql/master/conf/my.cnf:/etc/mysql/my.cnf \  # 挂载配置,若目录修改需同步变更
  -v /docker/mysql/master/data:/var/lib/mysql \            # 挂载数据(持久化),目录修改需同步变更
  -e MYSQL_ROOT_PASSWORD=root123 \  # 主库root密码,需自定义(如StrongPwd@2024)← 需修改为实际密码
  --restart=always \  # 开机自启(固定值,无需修改)
  mysql:5.7  # 镜像标签需与拉取的版本一致,若修改需同步 ← 需与步骤一拉取的镜像版本一致
  1. 验证主库配置是否生效

bash

# 1. 进入主库MySQL终端(密码需与启动时的MYSQL_ROOT_PASSWORD一致)
docker exec -it mysql-master mysql -uroot -proot123  # ← 替换为实际root密码

# 2. 检查关键参数(均需返回配置值,而非默认值)
show variables like 'server_id';        # 应返回步骤1中配置的server-id(如10)
show variables like 'gtid_mode';        # 应返回ON
show variables like 'log_bin';          # 应返回ON
show variables like 'enforce_gtid_consistency'; # 应返回ON
  1. 创建主从复制专用用户

sql

# 在主库MySQL终端执行:创建slave用户并授权
-- mysql5.7以上需分开执行
create user 'slave'@'192.168.1.%' identified by '123456';  # ← 需修改:'slave'为用户名,'192.168.1.%'为从库网段(确保包含从库IP),'123456'为密码
grant replication slave on *.* to 'slave'@'192.168.1.%';   # ← 用户名和网段需与上一行一致

# 刷新权限使配置生效
flush privileges;

# 临时设置主库为只读(避免配置期间写入数据,后续会解除)
set @@global.read_only=ON;

三、从服务器(192.168.1.196)操作:配置 GTID 与网络验证

  1. 先解决网络连通性(核心前提)

bash

# 1. 测试从库到主库3306端口的连通性(主库端口需与主库容器映射的主机端口一致)
nc -zv 192.168.1.190 3306  # ← 需修改:主库IP(192.168.1.190)和端口(3306,若主库修改需同步)
# 成功结果:Ncat: Connected to 192.168.1.190:3306.

# 2. 若失败(No route to host),排查方向:
# - 主库IP是否正确(主库执行ip addr确认)
# - 主从是否在同一网段(主从均执行ip addr,确保192.168.1.x)
# - 主库防火墙是否拦截(主库执行iptables -A INPUT -p tcp --dport 3306 -j ACCEPT)← 端口需与主库一致
  1. 创建从库挂载目录与配置文件

bash

# 1. 创建从库数据、配置目录(路径可自定义,需与后续挂载一致)
mkdir -p /docker/mysql/slave/data /docker/mysql/slave/conf  # ← 若修改路径,后续挂载需同步变更

# 2. 编写从库GTID配置文件(比主库多2个关键参数)
cat > /docker/mysql/slave/conf/my.cnf << EOF
[mysqld]
# 基础标识(必须与主库不同,从库设为20)
server-id = 20  # ← 可自定义(如2、200等),但需与主库server-id不同
# 中继日志(从库核心,存储主库同步的binlog,路径可自定义)
relay-log = /var/lib/mysql/relaylog  # ← 容器内路径,若修改需确保目录可写
relay-log-index = /var/lib/mysql/relaylog.index
# GTID关键配置(与主库一致)
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = 1
log_bin = /var/lib/mysql/mysql-bin  # 从库必须开启binlog(GTID要求)
# 从库专属配置
skip-slave-start = 1  # 容器启动时不自动启动同步(固定值,无需修改)
read-only = 1         # 从库默认只读(仅限制普通用户,root仍可写,固定值)
# 其他配置(与主库统一)
binlog_format = ROW
expire_logs_days = 7  # 可根据磁盘空间修改(如30天)
character-set-server = utf8mb4  # 需与主库一致,若主库修改需同步
collation-server = utf8mb4_unicode_ci
default_storage_engine = InnoDB
EOF

# 3. 修正配置文件权限(避免被MySQL忽略)
chmod 644 /docker/mysql/slave/conf/my.cnf
  1. 启动从库容器

bash

docker run -d \
  --name mysql-slave \  # 容器名可自定义(如slave-db)
  -p 3306:3306 \  # 若与主库同主机,改为主机端口如3308:3306(避免冲突)← 需修改主机端口(左侧)
  -v /docker/mysql/slave/conf/my.cnf:/etc/mysql/my.cnf \  # 挂载配置,目录修改需同步变更
  -v /docker/mysql/slave/data:/var/lib/mysql \            # 挂载数据,目录修改需同步变更
  -e MYSQL_ROOT_PASSWORD=root123 \  # 与主库root密码一致,需修改为实际密码 ← 需与主库root密码相同
  --restart=always \  # 开机自启(固定值,无需修改)
  mysql:5.7  # 镜像标签需与主库一致,若修改需同步 ← 需与步骤一拉取的镜像版本一致
  1. 验证从库配置是否生效

bash

# 1. 进入从库MySQL终端(密码需与启动时的MYSQL_ROOT_PASSWORD一致)
docker exec -it mysql-slave mysql -uroot -proot123  # ← 替换为实际root密码

# 2. 检查关键参数(均需返回配置值)
show variables like 'server_id';        # 应返回步骤2中配置的server-id(如20)
show variables like 'gtid_mode';        # 应返回ON
show variables like 'relay_log';        # 应返回/var/lib/mysql/relaylog(与配置一致)

四、配置 GTID 主从同步(从服务器操作)

  1. 执行同步命令(核心步骤)

sql

# 在从库MySQL终端执行:
# 1. 临时设置从库为只读(确保配置期间数据一致)
set @@global.read_only=ON;

# 2. 停止并重置同步状态(清空旧配置,首次部署也需执行)
stop slave;
reset slave;

# 3. 配置GTID同步(替换为主库实际信息)
change master to 
  master_host='192.168.1.190',    # 主库IP,需修改为实际主库IP ← 需修改为实际主库IP
  master_user='slave',            # 主库创建的复制用户,需与主库一致 ← 需与主库创建的用户名一致
  master_password='123456',       # 复制用户密码,需与主库一致 ← 需与主库设置的密码一致
  master_port=3306,               # 主库端口,需与主库容器映射的主机端口一致 ← 需修改为主库实际端口
  master_auto_position=1;         # GTID关键:自动定位同步位置(固定值,无需修改)

# 4. 启动从库同步进程
start slave;
  1. 验证同步状态(成功的核心标志)

sql

# 在从库MySQL终端执行(竖版显示,便于查看)
show slave status\G

# 重点检查以下2项,必须均为Yes:
# 1. Slave_IO_Running: Yes → IO线程正常(能从主库拉取binlog)
# 2. Slave_SQL_Running: Yes → SQL线程正常(能执行拉取的事务)

# 其他关键参数(辅助验证):
# - Retrieved_Gtid_Set: 非空 → 已拉取主库的GTID事务
# - Executed_Gtid_Set: 与Retrieved_Gtid_Set一致 → 已执行所有拉取的事务

五、解除只读与功能测试(主、从配合操作)

  1. 主库解除只读(主服务器操作)

bash

# 进入主库MySQL终端(密码需与主库root密码一致)
docker exec -it mysql-master mysql -uroot -proot123  # ← 替换为实际root密码

# 解除只读(允许业务写入数据)
set @@global.read_only=OFF;
  1. 测试数据同步(验证 GTID 生效)① 主库写入测试数据(主服务器操作)

sql

# 主库MySQL终端执行:
# 创建测试库(库名可自定义)
create database gtid_test;  # ← 库名可自定义(如test_db)
use gtid_test;

# 创建测试表并插入数据(表结构和数据可自定义)
create table user(id int, name varchar(20));  # ← 表名和字段可自定义
insert into user values(1, 'gtid_sync_test');  # ← 数据可自定义

② 从库验证同步结果(从服务器操作)

sql

# 从库MySQL终端执行:
# 查看是否同步到测试库(库名需与主库一致)
show databases like 'gtid_test';  # ← 需与主库创建的库名一致

# 查看测试表数据(若能看到主库插入的数据,同步成功)
use gtid_test;  # ← 需与主库库名一致
select * from user;  # ← 需与主库表名一致,应返回主库插入的数据

六、常见问题与解决方案

问题现象排查方向解决步骤执行服务器
配置文件被忽略(World-writable 警告)配置文件权限过高(777)chmod 644 /docker/mysql/xxx/conf/my.cnf(路径需与实际一致)← 需修改为实际配置文件路径主 / 从(对应服务器)
Slave_IO_Running: Connecting网络不通或复制用户错误1. nc -zv 主库IP 3306 验证网络(IP 和端口需实际值)← 需修改为主库实际 IP 和端口2. 主库重新授权:grant replication slave on *.* to 'slave'@'192.168.1.%' identified by '123456';(用户名、网段、密码需实际值)← 需修改为实际信息从库(网络测试)、主库(授权)
Slave_SQL_Running: No主从数据不一致1. 从库删除冲突表:drop table 冲突表名;(表名需实际值)← 需修改为冲突表名2. 重启同步:stop slave; start slave;从服务器
主库 show master status 空binlog 未开启检查主库 my.cnf 是否有 log_bin=mysql-bin,重启主库容器:docker restart mysql-master(容器名需实际值)← 需修改为实际容器名主服务器

七、最终确认清单

  • 主库:gtid_mode=ONlog_bin=ONserver_id=10(需与配置一致)→ 主服务器
  • 从库:gtid_mode=ONrelay_log 配置正确、server_id=20(需与配置一致)→ 从服务器
  • 网络:从库 nc -zv 主库IP 3306 成功(IP 和端口需实际值)→ 从服务器
  • 同步状态:从库 Slave_IO_Running=Yes 且 Slave_SQL_Running=Yes → 从服务器
  • 数据测试:主库写入数据,从库能同步 → 主、从服务器

完成以上步骤,基于 GTID 的 MySQL 主从复制架构即部署完成,后续可支持主库写入、从库只读查询,且切换主从时无需手动定位 binlog 文件和 pos 位置。

可以参考以下步骤来使用 Docker Compose 部署 WordPress 连接 MySQL 主从复制: 1. 创建一个 Docker Compose 文件 `docker-compose.yml`,并在其中定义两个服务:WordPress 和 MySQL。 ``` version: '3.8' services: db-master: image: mysql:5.7 command: --server-id=1 --log-bin=mysql-bin --binlog-format=row --gtid-mode=ON --enforce-gtid-consistency=ON --slave-skip-errors=all restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: wordpress volumes: - db-master:/var/lib/mysql networks: - wp-net db-slave: image: mysql:5.7 command: --server-id=2 --log-bin=mysql-bin --binlog-format=row --gtid-mode=ON --enforce-gtid-consistency=ON --slave-skip-errors=all --skip-log-slave-updates restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: wordpress MYSQL_MASTER_HOST: db-master MYSQL_MASTER_PASSWORD: password MYSQL_ALLOW_EMPTY_PASSWORD: "yes" volumes: - db-slave:/var/lib/mysql depends_on: - db-master networks: - wp-net wordpress: depends_on: - db-slave image: wordpress:latest ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db-slave WORDPRESS_DB_USER: root WORDPRESS_DB_PASSWORD: password WORDPRESS_DB_NAME: wordpress volumes: - wp-content:/var/www/html/wp-content networks: - wp-net volumes: db-master: db-slave: wp-content: networks: wp-net: ``` 2. 在 `db-master` 和 `db-slave` 服务中,分别使用 `--server-id` 设置不同的 ID;使用 `--log-bin` 启用二进制日志;使用 `--binlog-format` 设置二进制日志格式为行格式;使用 `--gtid-mode` 和 `--enforce-gtid-consistency` 启用 GTID 并强制要求一致性;使用 `--slave-skip-errors=all` 设置从库同步时遇到错误时跳过。 3. 在 `db-master` 服务中,使用 `MYSQL_ROOT_PASSWORD` 和 `MYSQL_DATABASE` 设置 root 用户的密码和数据库名;使用 `volumes` 把数据卷挂载到 `/var/lib/mysql` 目录。 4. 在 `db-slave` 服务中,使用 `MYSQL_ROOT_PASSWORD` 和 `MYSQL_DATABASE` 设置 root 用户的密码和数据库名;使用 `MYSQL_MASTER_HOST` 和 `MYSQL_MASTER_PASSWORD` 分别设置主库的主机名和密码;使用 `MYSQL_ALLOW_EMPTY_PASSWORD` 设置空密码;使用 `depends_on` 指定依赖的服务;使用 `volumes` 把数据卷挂载到 `/var/lib/mysql` 目录。 5. 在 `wordpress` 服务中,使用 `depends_on` 指定依赖的服务;使用 `WORDPRESS_DB_HOST`、`WORDPRESS_DB_USER`、`WORDPRESS_DB_PASSWORD` 和 `WORDPRESS_DB_NAME` 分别设置数据库的主机名、用户名、密码和数据库名;使用 `volumes` 把数据卷挂载到 `/var/www/html/wp-content` 目录。 6. 运行 `docker-compose up -d` 启动服务。 这样就可以使用 Docker Compose 部署 WordPress 连接 MySQL 主从复制了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值