MySQL 主从复制搭建记录

MySQL 主从复制搭建记录

团队项目到了一定规模,读写压力开始明显,需要做读写分离。搭主从是前提,这里记录用 Docker 搭建 MySQL 主从复制的完整过程。


1、基于 Docker 部署 MySQL

# 启动 MySQL 容器,命令行参数直接开启 binlog 并设置 server-id,免得改配置文件
docker run -p 3306:3306 --name mysql \
-v /home/mydata/mysql/db:/var/lib/mysql \
-v /home/mydata/mysql/conf:/etc/mysql/conf.d \
-v /home/mydata/mysql/log:/var/log/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--restart=always \
-d mysql:8.0.27 \
--lower_case_table_names=1 \
--server-id=3306

同一服务器部署多实例时,映射到不同的主机端口,server-id 各不相同。


2、主从配置说明

主从复制依赖 binlog,核心参数:

log-bin=mysql-bin   # 开启二进制日志(必须)
server-id=xxx # 服务器唯一 ID,主从节点不能相同(必须)

使用上面的 Docker 启动命令已通过 --server-id=3306 参数直接生效,无需修改 my.cnf

验证配置:

SHOW VARIABLES LIKE 'log_%';
-- log_bin = ON 即为开启

SELECT @@server_id;
-- 返回值为配置的 server-id

3、Master 节点配置

在主库创建供 slave 连接的专用账号:

-- 创建用户(允许远程连接)
CREATE USER 'copy'@'%' IDENTIFIED BY '密码';

-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'copy'@'%';

-- 刷新权限
FLUSH PRIVILEGES;

查看主库状态,记录 FilePosition 的值(slave 配置需要用到):

SHOW MASTER STATUS;
-- 如果 Position 值很大,说明不是初始状态,可以先重置
RESET MASTER;

⚠️ 记录完 FilePosition 后,不要再操作主库,防止状态值变化。


4、Slave 节点配置

-- 检查初始状态(结果为空表示未配置过)
SHOW SLAVE STATUS;

-- 配置连接主库
CHANGE MASTER TO
master_host='主库IP',
master_user='copy',
master_password='密码',
master_log_file='binlog.000001', -- 主库 SHOW MASTER STATUS 查出的 File
master_log_pos=156; -- 主库 SHOW MASTER STATUS 查出的 Position

-- 启动复制
START SLAVE;

-- 查看状态
SHOW SLAVE STATUS \G;

关键指标:

  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes

两个都是 YES 才算正常。如果是 NO 或 Connecting,查看 Last_IO_Error / Last_SQL_Error 字段排查原因。

如需重新配置:STOP SLAVE; RESET SLAVE ALL; 然后重新执行 CHANGE MASTER。


5、验证和后续

-- 在 master 上查看有哪些 slave 连接
SHOW SLAVE HOSTS;
-- 或者
SELECT * FROM information_schema.processlist WHERE command = 'Binlog Dump';

配置完成后在 master 上做增删改操作,在 slave 上查询验证数据是否同步。

读写分离建议: 从库推荐新建只读权限用户,应用程序只通过只读账号连从库。


6、扩展:GTID 模式简介

GTID(Global Transaction Identifier)是 MySQL 主从架构的另一种复制方式,比传统 binlog + position 更稳定,故障切换更简单。

优点:

  • 搭建更简单,不需要手动记录 binlog file 和 position
  • GTID 连续递增,数据一致性保障更强
  • 故障切换时间更短

缺点(使用限制):

  • 主从表存储引擎必须一致(都是 InnoDB)
  • 不支持 CREATE TABLE ... AS SELECT 语句
  • 不支持 CREATE/DROP TEMPORARY TABLE
  • 不支持用 sql_slave_skip_counter 跳过错误

目前未实践 GTID 模式,仅作记录,后续补充实践经验。

参考资料: