MySQL 集群搭建全攻略:从一主一从到双主双从(超详细·配置解析)
一、什么是数据库集群?
数据库集群是指将多台数据库服务器组合在一起,通过网络协同工作,对外提供统一的数据服务。集群的主要目标通常是:
-
高可用性:当某台服务器故障时,其他节点可以接管服务,减少停机时间。
-
读写分离与负载均衡:主库处理写操作,从库分担读请求,提升系统整体吞吐量。
-
数据冗余:数据在多个节点上存在副本,防止数据丢失。
MySQL 最常见的两种集群方案是一主一从和双主双从。本文将带你从基础的一主一从搭建,进阶到生产环境常用的双主双从架构,并深度解析核心配置项。
二、一主一从集群搭建
2.1 环境准备
| 角色 | 操作系统 | IP 地址 | MySQL 版本 |
|---|---|---|---|
| Master | CentOS 7 | 192.168.10.10 | 8.0.33 |
| Slave | CentOS 7 | 192.168.10.20 | 8.0.33 |
前置要求:
-
两台服务器均已安装相同版本的 MySQL,并已启动服务。
-
两台服务器之间网络互通,防火墙开放 MySQL 默认端口
3306。 -
主服务器上有可供复制的数据库(例如
test_db)及数据。
2.2 主服务器配置(Master)
1. 修改配置文件 /etc/my.cnf
在 [mysqld] 段落中添加或修改以下内容:
ini
[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
binlog_do_db = test_db
expire_logs_days = 7
sync_binlog = 1
操作文件:/etc/my.cnf
保存后重启 MySQL 服务:
bash
systemctl restart mysqld
2. 创建用于复制的账号并授权
sql
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'Repl@Pass123';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;
3. 记录二进制日志坐标
sql
SHOW MASTER STATUS;
记下输出中的 File(如 mysql-bin.000001)和 Position(如 856)。
2.3 从服务器配置(Slave)
1. 修改配置文件 /etc/my.cnf
ini
[mysqld]
server-id = 2
relay_log = mysql-relay-bin
read_only = 1
replicate_do_db = test_db
操作文件:/etc/my.cnf
重启从库 MySQL:
bash
systemctl restart mysqld
2. 设置主库信息并启动复制
sql
STOP SLAVE;
CHANGE MASTER TO
MASTER_HOST='192.168.10.10',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='Repl@Pass123',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=856;
START SLAVE;
3. 查看复制状态
sql
SHOW SLAVE STATUS\G;
确认 Slave_IO_Running 和 Slave_SQL_Running 均为 Yes。
2.4 验证同步
在主库执行:
sql
CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20));
INSERT INTO t1 VALUES (1, 'hello master-slave');
到从库查询:
sql
SELECT * FROM t1;
若能查到数据,则一主一从搭建成功。
三、双主双从集群搭建
3.1 什么是双主双从?
双主双从是两台服务器互为主从(Master-Master),同时各自带一个从库。这种架构既能实现读写分离,又能在任一主库故障时,由另一主库继续提供写服务,高可用性更强。架构示意:
text
[Master1] <---双向复制---> [Master2]
| |
v v
[Slave1] [Slave2]
-
Master1 和 Master2 互相复制,组成双主,都可接收写入。
-
Slave1 复制 Master1,Slave2 复制 Master2,用于读流量分担。
-
应用层可通过中间件将写操作分摊到两个主库(注意避免冲突),读操作发送给就近的从库。
3.2 环境准备
| 角色 | IP 地址 | 说明 |
|---|---|---|
| Master1 | 192.168.10.11 | 主库1 |
| Master2 | 192.168.10.12 | 主库2 |
| Slave1 | 192.168.10.21 | Master1的从库 |
| Slave2 | 192.168.10.22 | Master2的从库 |
为便于演示,四台服务器均安装 MySQL 8.0,已有一个业务库
test_db。
3.3 解决自增主键冲突
双主架构中,两个主库都可能插入数据,若使用自增主键极易发生冲突。MySQL 提供 auto_increment_increment 和 auto_increment_offset 参数让不同主库生成互不冲突的自增 ID。
-
设置步长
auto_increment_increment = 2(节点数)。 -
设置起始偏移量:Master1 偏移为
1,Master2 偏移为2。 -
这样 Master1 生成的自增 ID 依次为:1, 3, 5, 7...;Master2 为:2, 4, 6, 8...,完美错开。
3.4 Master1 配置
操作文件:/etc/my.cnf
ini
[mysqld]
# 基础配置
server-id = 11
log_bin = mysql-bin
binlog_format = ROW
sync_binlog = 1
expire_logs_days = 7
# 需要复制的数据库
binlog_do_db = test_db
# 自增步长与偏移,解决双主冲突
auto_increment_increment = 2
auto_increment_offset = 1
# 从库更新也要写入 binlog,否则无法级联复制到另一个主库
log_slave_updates = 1
# 避免循环复制(多主时防止复制回路)
replicate_same_server_id = 0
重启 MySQL:
bash
systemctl restart mysqld
创建复制用户并记录日志坐标:
sql
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'Repl@Pass123';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS; -- 假设得到 mysql-bin.000001, pos=1074
3.5 Master2 配置
操作文件:/etc/my.cnf
ini
[mysqld]
server-id = 12
log_bin = mysql-bin
binlog_format = ROW
sync_binlog = 1
expire_logs_days = 7
binlog_do_db = test_db
auto_increment_increment = 2
auto_increment_offset = 2 # 注意偏移为2
log_slave_updates = 1
replicate_same_server_id = 0
重启 MySQL,创建相同复制用户并记录 Master 状态:
sql
SHOW MASTER STATUS; -- 假设得到 mysql-bin.000001, pos=1123
3.6 建立双主互备复制
在 Master1 上配置到 Master2 的同步
sql
STOP SLAVE;
CHANGE MASTER TO
MASTER_HOST='192.168.10.12',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='Repl@Pass123',
MASTER_LOG_FILE='mysql-bin.000001', -- Master2 的 File
MASTER_LOG_POS=1123; -- Master2 的 Position
START SLAVE;
在 Master2 上配置到 Master1 的同步
sql
STOP SLAVE;
CHANGE MASTER TO
MASTER_HOST='192.168.10.11',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='Repl@Pass123',
MASTER_LOG_FILE='mysql-bin.000001', -- Master1 的 File
MASTER_LOG_POS=1074; -- Master1 的 Position
START SLAVE;
分别在两台主库执行 SHOW SLAVE STATUS\G,确保 IO 和 SQL 线程运行正常。此时双主互备已生效。
3.7 配置两个从库
Slave1(复制 Master1)
操作文件:/etc/my.cnf
ini
[mysqld]
server-id = 21
relay_log = mysql-relay-bin
read_only = 1
replicate_do_db = test_db
重启后执行:
sql
CHANGE MASTER TO
MASTER_HOST='192.168.10.11',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='Repl@Pass123',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=1074;
START SLAVE;
Slave2(复制 Master2)
操作文件:/etc/my.cnf
ini
[mysqld]
server-id = 22
relay_log = mysql-relay-bin
read_only = 1
replicate_do_db = test_db
重启后执行:
sql
CHANGE MASTER TO
MASTER_HOST='192.168.10.12',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='Repl@Pass123',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=1123;
START SLAVE;
3.8 验证双主双从同步
在 Master1 插入数据:
sql
INSERT INTO test_db.t1 (name) VALUES ('from master1');
此时 Master2 会通过互备同步该记录,Slave1 和 Slave2 也会依次获得数据。在 Master2 插入:
sql
INSERT INTO test_db.t1 (name) VALUES ('from master2');
观察四台服务器上的数据,应全部一致,且自增主键无冲突。
四、核心配置文件关键字深度解析
下面对两种架构中出现的参数统一进行详解:
| 参数 | 用途说明 |
|---|---|
| server-id | 全局唯一实例标识。主从、双主中每个节点必须不同,MySQL 靠它区分复制事件来源,防止循环复制。 |
| log_bin | 开启二进制日志,指定日志文件前缀。所有数据变更都记录在此,是复制的基础。 |
| binlog_format | 日志格式。推荐 ROW 行模式,记录每行数据变化,避免主从不一致。 |
| sync_binlog | 事务提交时是否同步磁盘。1 最安全但性能略有下降,高可用集群建议设为 1。 |
| expire_logs_days | 二进制日志保留天数,避免磁盘耗尽。 |
| binlog_do_db | 白名单,仅记录指定数据库的二进制日志。 |
| binlog_ignore_db | 黑名单,忽略指定库的日志。注意不要与 do 混用导致不可预期行为。 |
| relay_log | 从库的中继日志。IO 线程将主库 binlog 拉取后写入中继日志,SQL 线程再执行。 |
| read_only | 从库设为 1 后,普通用户不可写,防止误操作破坏数据一致性。 |
| replicate_do_db / replicate_ignore_db | 从库级别的复制过滤,控制哪些库的更新被应用。 |
| auto_increment_increment | 自增步长,通常设为参与写操作的节点数(双主设为 2)。 |
| auto_increment_offset | 自增起始偏移,用于区分不同节点生成的主键范围。 |
| log_slave_updates | 从库接收到的更新是否写入自己的 binlog。在双主或级联复制中必须开启,否则变更无法传递给下一级节点。 |
| replicate_same_server_id | 是否应用自身 Server ID 产生的事件。默认关闭(0),避免循环复制。 |
常见扩展参数
-
gtid_mode / enforce_gtid_consistency:开启 GTID 复制,简化故障切换。双主场景强烈建议使用 GTID,可避免繁琐的日志位点对齐。
-
slave_parallel_workers:从库并行复制线程数,提升回放速度。
-
master_info_repository / relay_log_info_repository:设为
TABLE(MySQL 8.0 默认),将复制信息存储在 InnoDB 表中,可靠性更高。
五、常见问题排查
-
IO 线程异常
网络不通、防火墙未放行、复制用户密码错误。查看Last_IO_Error定位。 -
SQL 线程异常
主键冲突、表结构不一致等。查看Last_SQL_Error,修复后可START SLAVE继续。 -
双主自增冲突
检查两台主库auto_increment_offset是否正确错开,且所有表的存储引擎使用自增时都会受该参数影响。 -
循环复制导致数据翻倍
确保replicate_same_server_id = 0且每台服务器的server-id唯一,同时建议使用 GTID。 -
从库延迟过大
可增加slave_parallel_workers,并优化主库写入的批量操作。
六、总结
本文从一主一从的基础架构讲起,逐步过渡到生产环境更常用的双主双从方案。通过详尽的配置示例和参数解析,帮助你掌握:
-
基于日志位点的传统主从复制搭建
-
双主互备架构中自增 ID 冲突的解决思路
-
log_slave_updates、replicate_same_server_id等双主特有参数的作用
下一步你可以:
-
引入 GTID 模式,让主从切换更方便
-
使用 半同步复制 进一步保障数据一致性
-
结合 ProxySQL 或 Atlas 实现自动读写分离与高可用
更多推荐



所有评论(0)